Changed tas to spaces

This commit is contained in:
Ziver Koc 2018-05-26 23:01:03 +02:00
parent a938b70d57
commit b1c53d88ae
196 changed files with 14016 additions and 14035 deletions

View file

@ -40,203 +40,203 @@ import java.util.Random;
* Basic symmetric encryption example
*/
public class Encrypter {
// Choices are available at: http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html
public enum Algorithm {
/** Advanced Encryption Standard as specified by NIST in FIPS 197. Also known as the Rijndael algorithm by Joan Daemen and Vincent Rijmen, AES is a 128-bit block cipher supporting keys of 128, 192, and 256 bits. **/
AES,
/** The AES key wrapping algorithm as described in RFC 3394. **/
AESWrap,
/** A stream cipher believed to be fully interoperable with the RC4 cipher developed by Ron Rivest. For more information, see K. Kaukonen and R. Thayer, "A Stream Cipher Encryption Algorithm 'Arcfour'", Internet Draft (expired), draft-kaukonen-cipher-arcfour-03.txt. **/
ARCFOUR,
/** The Blowfish block cipher designed by Bruce Schneier. **/
Blowfish,
/** Counter/CBC Mode, as defined in NIST Special Publication SP 800-38C. **/
CCM,
/** The Digital Encryption Standard as described in FIPS PUB 46-3. **/
DES,
/** Triple DES Encryption (also known as DES-EDE, 3DES, or Triple-DES). Data is encrypted using the DES algorithm three separate times. It is first encrypted using the first subkey, then decrypted with the second subkey, and encrypted with the third subkey. **/
DESede,
/** The DESede key wrapping algorithm as described in RFC 3217 . **/
DESedeWrap,
/** Elliptic Curve Integrated Encryption Scheme **/
ECIES,
/** Galois/Counter Mode, as defined in NIST Special Publication SP 800-38D. **/
GCM,
/** Variable-key-size encryption algorithms developed by Ron Rivest for RSA Data Security, Inc. **/
RC2,
/** Variable-key-size encryption algorithms developed by Ron Rivest for RSA Data Security, Inc. (See note prior for ARCFOUR.) **/
RC4,
/** Variable-key-size encryption algorithms developed by Ron Rivest for RSA Data Security, Inc. **/
RC5,
/** The RSA encryption algorithm as defined in PKCS #1 **/
RSA
}
public enum Digest {
MD2,
MD5,
SHA1,
SHA256,
SHA384,
SHA512,
HmacMD5,
HmacSHA1,
HmacSHA256,
HmacSHA384,
HmacSHA512
}
// Choices are available at: http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html
public enum Algorithm {
/** Advanced Encryption Standard as specified by NIST in FIPS 197. Also known as the Rijndael algorithm by Joan Daemen and Vincent Rijmen, AES is a 128-bit block cipher supporting keys of 128, 192, and 256 bits. **/
AES,
/** The AES key wrapping algorithm as described in RFC 3394. **/
AESWrap,
/** A stream cipher believed to be fully interoperable with the RC4 cipher developed by Ron Rivest. For more information, see K. Kaukonen and R. Thayer, "A Stream Cipher Encryption Algorithm 'Arcfour'", Internet Draft (expired), draft-kaukonen-cipher-arcfour-03.txt. **/
ARCFOUR,
/** The Blowfish block cipher designed by Bruce Schneier. **/
Blowfish,
/** Counter/CBC Mode, as defined in NIST Special Publication SP 800-38C. **/
CCM,
/** The Digital Encryption Standard as described in FIPS PUB 46-3. **/
DES,
/** Triple DES Encryption (also known as DES-EDE, 3DES, or Triple-DES). Data is encrypted using the DES algorithm three separate times. It is first encrypted using the first subkey, then decrypted with the second subkey, and encrypted with the third subkey. **/
DESede,
/** The DESede key wrapping algorithm as described in RFC 3217 . **/
DESedeWrap,
/** Elliptic Curve Integrated Encryption Scheme **/
ECIES,
/** Galois/Counter Mode, as defined in NIST Special Publication SP 800-38D. **/
GCM,
/** Variable-key-size encryption algorithms developed by Ron Rivest for RSA Data Security, Inc. **/
RC2,
/** Variable-key-size encryption algorithms developed by Ron Rivest for RSA Data Security, Inc. (See note prior for ARCFOUR.) **/
RC4,
/** Variable-key-size encryption algorithms developed by Ron Rivest for RSA Data Security, Inc. **/
RC5,
/** The RSA encryption algorithm as defined in PKCS #1 **/
RSA
}
public enum Digest {
MD2,
MD5,
SHA1,
SHA256,
SHA384,
SHA512,
HmacMD5,
HmacSHA1,
HmacSHA256,
HmacSHA384,
HmacSHA512
}
// 8-byte Salt
public static byte[] salt = {
(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
(byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
};
// 8-byte Salt
public static byte[] salt = {
(byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32,
(byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03
};
private Cipher encipher;
private Cipher decipher;
private Key key;
private AlgorithmParameterSpec paramSpec;
private Cipher encipher;
private Cipher decipher;
private Key key;
private AlgorithmParameterSpec paramSpec;
/**
* Generates a random key
* @param crypto is algorithm to encrypt/decrypt with
*/
public Encrypter(Algorithm crypto) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException{
KeyGenerator keygenerator = KeyGenerator.getInstance(crypto.toString());
/**
* Generates a random key
* @param crypto is algorithm to encrypt/decrypt with
*/
public Encrypter(Algorithm crypto) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException{
KeyGenerator keygenerator = KeyGenerator.getInstance(crypto.toString());
key = keygenerator.generateKey();
encipher = Cipher.getInstance(key.getAlgorithm());
decipher = Cipher.getInstance(key.getAlgorithm());
encipher.init(Cipher.ENCRYPT_MODE, key);
decipher.init(Cipher.DECRYPT_MODE, key);
}
key = keygenerator.generateKey();
encipher = Cipher.getInstance(key.getAlgorithm());
decipher = Cipher.getInstance(key.getAlgorithm());
encipher.init(Cipher.ENCRYPT_MODE, key);
decipher.init(Cipher.DECRYPT_MODE, key);
}
/**
* Uses the given key for encryption
* @param key is an existing key to use for encrypting/decrypting
*/
public Encrypter(Key key) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException{
this.key = key;
encipher = Cipher.getInstance(key.getAlgorithm());
decipher = Cipher.getInstance(key.getAlgorithm());
encipher.init(Cipher.ENCRYPT_MODE, key);
decipher.init(Cipher.DECRYPT_MODE, key);
}
/**
* Uses the given key for encryption
* @param key is an existing key to use for encrypting/decrypting
*/
public Encrypter(Key key) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException{
this.key = key;
encipher = Cipher.getInstance(key.getAlgorithm());
decipher = Cipher.getInstance(key.getAlgorithm());
encipher.init(Cipher.ENCRYPT_MODE, key);
decipher.init(Cipher.DECRYPT_MODE, key);
}
/**
* Creates a encrypter with a passphrase.
*
* @param stringKey is a passphrase to use as key
* @param crypto is algorithm to encrypt/decrypt with
*/
public Encrypter(String stringKey, Algorithm crypto) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException {
this(stringKey, Digest.HmacSHA1, crypto, 500,
(crypto==Algorithm.DES ? 64 : 128));
}
/**
* Creates a encrypter with a passphrase.
*
* @param stringKey is a passphrase to use as key
* @param crypto is algorithm to encrypt/decrypt with
*/
public Encrypter(String stringKey, Algorithm crypto) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, InvalidKeyException {
this(stringKey, Digest.HmacSHA1, crypto, 500,
(crypto==Algorithm.DES ? 64 : 128));
}
public Encrypter(String stringKey, Digest digest, Algorithm crypto, int iteration, int keyBitSize) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException {
// Install SunJCE provider
Provider sunJce = new com.sun.crypto.provider.SunJCE();
Security.addProvider(sunJce);
public Encrypter(String stringKey, Digest digest, Algorithm crypto, int iteration, int keyBitSize) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException {
// Install SunJCE provider
Provider sunJce = new com.sun.crypto.provider.SunJCE();
Security.addProvider(sunJce);
// Generate the secret key specs.
//String instance = "PBEWith"+ digest +"And"+ crypto;
String instance = "PBKDF2With"+ digest;
SecretKeyFactory factory = SecretKeyFactory.getInstance(instance);
KeySpec keySpec = new PBEKeySpec(stringKey.toCharArray(), salt, iteration, keyBitSize);
SecretKey tmp = factory.generateSecret(keySpec);
key = new SecretKeySpec(tmp.getEncoded(), crypto.toString());
//key = new SecretKeySpec(stringKey.getBytes(), crypto.toString());
// Generate the secret key specs.
//String instance = "PBEWith"+ digest +"And"+ crypto;
String instance = "PBKDF2With"+ digest;
SecretKeyFactory factory = SecretKeyFactory.getInstance(instance);
KeySpec keySpec = new PBEKeySpec(stringKey.toCharArray(), salt, iteration, keyBitSize);
SecretKey tmp = factory.generateSecret(keySpec);
key = new SecretKeySpec(tmp.getEncoded(), crypto.toString());
//key = new SecretKeySpec(stringKey.getBytes(), crypto.toString());
encipher = Cipher.getInstance(key.getAlgorithm());
decipher = Cipher.getInstance(key.getAlgorithm());
encipher.init(Cipher.ENCRYPT_MODE, key);
decipher.init(Cipher.DECRYPT_MODE, key);
}
encipher = Cipher.getInstance(key.getAlgorithm());
decipher = Cipher.getInstance(key.getAlgorithm());
encipher.init(Cipher.ENCRYPT_MODE, key);
decipher.init(Cipher.DECRYPT_MODE, key);
}
/**
* Encrypts the given data
*
* @param data is the data to encrypt
* @return The encrypted data
*/
public byte[] encrypt(byte[] data){
try {
byte[] encryption = new byte[encipher.getOutputSize(data.length)];
int ctLength = encipher.update(data, 0, data.length, encryption, 0);
/**
* Encrypts the given data
*
* @param data is the data to encrypt
* @return The encrypted data
*/
public byte[] encrypt(byte[] data){
try {
byte[] encryption = new byte[encipher.getOutputSize(data.length)];
int ctLength = encipher.update(data, 0, data.length, encryption, 0);
ctLength += encipher.doFinal(encryption, ctLength);
return encryption;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
ctLength += encipher.doFinal(encryption, ctLength);
return encryption;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Adds encryption to the OutputStream
* @param out is the OutputStream to enable encryption on
* @return A new encrypted OutputStream
*/
public OutputStream encrypt(OutputStream out) {
// Bytes written to out will be encrypted
return new CipherOutputStream(out, encipher);
/**
* Adds encryption to the OutputStream
* @param out is the OutputStream to enable encryption on
* @return A new encrypted OutputStream
*/
public OutputStream encrypt(OutputStream out) {
// Bytes written to out will be encrypted
return new CipherOutputStream(out, encipher);
}
}
/**
* Decrypts encrypted data
* @param encrypted is the encrypted data
* @return The decrypted data
*/
public byte[] decrypt(byte[] encrypted){
try {
byte[] dataTmp = new byte[encrypted.length];
int ptLength = decipher.update(encrypted, 0, encrypted.length, dataTmp, 0);
ptLength += decipher.doFinal(dataTmp, ptLength);
/**
* Decrypts encrypted data
* @param encrypted is the encrypted data
* @return The decrypted data
*/
public byte[] decrypt(byte[] encrypted){
try {
byte[] dataTmp = new byte[encrypted.length];
int ptLength = decipher.update(encrypted, 0, encrypted.length, dataTmp, 0);
ptLength += decipher.doFinal(dataTmp, ptLength);
byte[] data = new byte[ptLength];
System.arraycopy(dataTmp, 0, data, 0, ptLength);
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
byte[] data = new byte[ptLength];
System.arraycopy(dataTmp, 0, data, 0, ptLength);
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Adds decryption to the InputStream
* @param in is the InputStream to enable decryption on
* @return A new decrypted InputStream
*/
public InputStream decrypt(InputStream in) {
// Bytes read from in will be decrypted
return new CipherInputStream(in, decipher);
/**
* Adds decryption to the InputStream
* @param in is the InputStream to enable decryption on
* @return A new decrypted InputStream
*/
public InputStream decrypt(InputStream in) {
// Bytes read from in will be decrypted
return new CipherInputStream(in, decipher);
}
}
/**
* @return The key for this encrypter
*/
public Key getKey(){
return key;
}
/**
* @return The key for this encrypter
*/
public Key getKey(){
return key;
}
/**
* @return the algorithm used by this encrypter
*/
public String getAlgorithm(){
return key.getAlgorithm();
}
/**
* @return the algorithm used by this encrypter
*/
public String getAlgorithm(){
return key.getAlgorithm();
}
/**
* Randomizes the salt for the key
*/
public static void randomizeSalt(){
Random random = new Random();
random.nextBytes(salt);
}
/**
* Randomizes the salt for the key
*/
public static void randomizeSalt(){
Random random = new Random();
random.nextBytes(salt);
}
}

View file

@ -37,133 +37,133 @@ import java.security.NoSuchAlgorithmException;
public class Hasher {
/**
* Returns a hash of a file
*
* @param file is the path to the file
* @param hashType is the hash type
* @return a String with the hash
*/
public static String hash(File file, String hashType) throws NoSuchAlgorithmException, IOException {
MessageDigest digest = MessageDigest.getInstance(hashType); //"MD5"
InputStream is = new FileInputStream(file);
String output = "";
byte[] buffer = new byte[8192];
int read = 0;
try {
while( (read = is.read(buffer)) > 0) {
digest.update(buffer, 0, read);
}
byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
output = bigInt.toString(16);
}
catch(IOException e) {
throw new RuntimeException("Unable to process file for "+hashType+" hash", e);
}
is.close();
/**
* Returns a hash of a file
*
* @param file is the path to the file
* @param hashType is the hash type
* @return a String with the hash
*/
public static String hash(File file, String hashType) throws NoSuchAlgorithmException, IOException {
MessageDigest digest = MessageDigest.getInstance(hashType); //"MD5"
InputStream is = new FileInputStream(file);
String output = "";
byte[] buffer = new byte[8192];
int read = 0;
try {
while( (read = is.read(buffer)) > 0) {
digest.update(buffer, 0, read);
}
byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
output = bigInt.toString(16);
}
catch(IOException e) {
throw new RuntimeException("Unable to process file for "+hashType+" hash", e);
}
is.close();
return output;
}
return output;
}
/**
* Returns the MD5 hash of the given object
*
* @param str is the String to hash
* @return an String containing the hash
*/
public static String MD5(String str){
try {
return hash(str, "MD5");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Returns the MD5 hash of the given object
*
* @param str is the String to hash
* @return an String containing the hash
*/
public static String MD5(String str){
try {
return hash(str, "MD5");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Returns the MD5 hash of the given object
*
* @param object is the object to hash
* @return an String containing the hash
*/
public static String MD5(Serializable object){
try {
return hash(object, "MD5");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Returns the MD5 hash of the given file
*
* @param file is the file to hash
* @return an String containing the hash
*/
public static String MD5(File file) throws IOException{
try {
return hash(file, "MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* Returns the MD5 hash of the given object
*
* @param object is the object to hash
* @return an String containing the hash
*/
public static String MD5(Serializable object){
try {
return hash(object, "MD5");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Returns the SHA-1 hash of the given object
*
* @param str is the String to hash
* @return an String containing the hash
*/
public static String SHA1(String str){
try {
return hash(str, "SHA-1");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Returns the SHA-1 hash of the given object
*
* @param object is the object to hash
* @return an String containing the hash
*/
public static String SHA1(Serializable object){
try {
return hash(object, "SHA-1");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Returns the SHA-256 hash with a key for the given String
*
* @param str is the String to hash
* @param key is the key to use with the hash
* @return an String containing the hash
*/
public static String HMAC_SHA256(String str, String key){
return HMAC("HmacSHA256", str.getBytes(), key.getBytes());
}
/**
* Returns a HMAC hash with a key for the given String
*
* @param algo specifies the algorithm to be used
* @param data is the String to hash
* @param key is the key to use with the hash
* @return an String containing the hash
*/
public static String HMAC(String algo, byte[] data, byte[] key){
try {
// Get an hmac_sha1 key from the raw key bytes
/**
* Returns the MD5 hash of the given file
*
* @param file is the file to hash
* @return an String containing the hash
*/
public static String MD5(File file) throws IOException{
try {
return hash(file, "MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* Returns the SHA-1 hash of the given object
*
* @param str is the String to hash
* @return an String containing the hash
*/
public static String SHA1(String str){
try {
return hash(str, "SHA-1");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Returns the SHA-1 hash of the given object
*
* @param object is the object to hash
* @return an String containing the hash
*/
public static String SHA1(Serializable object){
try {
return hash(object, "SHA-1");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Returns the SHA-256 hash with a key for the given String
*
* @param str is the String to hash
* @param key is the key to use with the hash
* @return an String containing the hash
*/
public static String HMAC_SHA256(String str, String key){
return HMAC("HmacSHA256", str.getBytes(), key.getBytes());
}
/**
* Returns a HMAC hash with a key for the given String
*
* @param algo specifies the algorithm to be used
* @param data is the String to hash
* @param key is the key to use with the hash
* @return an String containing the hash
*/
public static String HMAC(String algo, byte[] data, byte[] key){
try {
// Get an hmac_sha1 key from the raw key bytes
SecretKeySpec signingKey = new SecretKeySpec(key, algo);
// Get a MAC instance and initialize with the signing key
@ -174,11 +174,11 @@ public class Hasher {
byte[] raw = mac.doFinal( data );
return Converter.toHexString(raw);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String PBKDF2(String data, String salt, int iterations){
try {
@ -196,97 +196,97 @@ public class Hasher {
}
return null;
}
/**
* Hashes the given String as UTF8
*
* @param object is the String
* @param hashType is the hash algorithm (MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512 )
* @return a hex String of the hash
*/
public static String hash(String object, String hashType) throws Exception {
return hash(object.getBytes(), hashType);//(new BASE64Encoder()).encode(raw);
}
/**
* Returns the hash of the given object
*
* @param object is the object to hash
* @param hashType is the hash method (MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512 )
* @return an String containing the hash
*/
public static String hash(Serializable object, String hashType) throws Exception {
return hash(Converter.toBytes(object), hashType);//(new BASE64Encoder()).encode(raw);
}
/**
* Hashes a given byte array
*
* @param data is the byte array to hash
* @param hashType is the hash method (MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512 )
* @return an String containing the hash
* @throws Exception
*/
public static String hash(byte[] data, String hashType) throws Exception {
MessageDigest md = null;
md = MessageDigest.getInstance(hashType); //MD5 || SHA
md.update(data);
/**
* Hashes the given String as UTF8
*
* @param object is the String
* @param hashType is the hash algorithm (MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512 )
* @return a hex String of the hash
*/
public static String hash(String object, String hashType) throws Exception {
return hash(object.getBytes(), hashType);//(new BASE64Encoder()).encode(raw);
}
byte raw[] = md.digest();
return Converter.toHexString(raw);//(new BASE64Encoder()).encode(raw);
}
/**
* Returns the hash of the given object
*
* @param object is the object to hash
* @param hashType is the hash method (MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512 )
* @return an String containing the hash
*/
public static String hash(Serializable object, String hashType) throws Exception {
return hash(Converter.toBytes(object), hashType);//(new BASE64Encoder()).encode(raw);
}
/**
* MurmurHash2 ported from c++ source
*
* @param object is the Key
* @param seed is the seed
* @return A MurmurHash of the key
*/
public static int MurmurHash(Serializable object, int seed) throws Exception{
byte[] data = Converter.toBytes(object);
int length = data.length;
/**
* Hashes a given byte array
*
* @param data is the byte array to hash
* @param hashType is the hash method (MD2, MD5, SHA-1, SHA-256, SHA-384, SHA-512 )
* @return an String containing the hash
* @throws Exception
*/
public static String hash(byte[] data, String hashType) throws Exception {
MessageDigest md = null;
md = MessageDigest.getInstance(hashType); //MD5 || SHA
md.update(data);
//Constants
int m = 0x5bd1e995;
int r = 24;
byte raw[] = md.digest();
return Converter.toHexString(raw);//(new BASE64Encoder()).encode(raw);
}
// Initialize the hash to a 'random' value
int h = seed ^ length;
/**
* MurmurHash2 ported from c++ source
*
* @param object is the Key
* @param seed is the seed
* @return A MurmurHash of the key
*/
public static int MurmurHash(Serializable object, int seed) throws Exception{
byte[] data = Converter.toBytes(object);
int length = data.length;
int i=0;
for(; i+4<length ;i+=4){
// get the first 4 bytes
int k = data[i+3] & 0xff;
k <<= 8;
k |= data[i+2] & 0xff;
k <<= 8;
k |= data[i+1] & 0xff;
k <<= 8;
k |= data[i+0] & 0xff;
//Constants
int m = 0x5bd1e995;
int r = 24;
k *= m;
k ^= k >>> r;
k *= m;
// Initialize the hash to a 'random' value
int h = seed ^ length;
h *= m;
h ^= k;
}
int i=0;
for(; i+4<length ;i+=4){
// get the first 4 bytes
int k = data[i+3] & 0xff;
k <<= 8;
k |= data[i+2] & 0xff;
k <<= 8;
k |= data[i+1] & 0xff;
k <<= 8;
k |= data[i+0] & 0xff;
// Handle the last few bytes of the input
i = length % 4;
k *= m;
k ^= k >>> r;
k *= m;
switch(i){
case 3: h ^= data[length-3] << 16;
case 2: h ^= data[length-2] << 8;
case 1: h ^= data[length-1];
h *= m;
}
h *= m;
h ^= k;
}
h ^= h >>> 13;
h *= m;
h ^= h >>> 15;
// Handle the last few bytes of the input
i = length % 4;
return h;
}
switch(i){
case 3: h ^= data[length-3] << 16;
case 2: h ^= data[length-2] << 8;
case 1: h ^= data[length-1];
h *= m;
}
h ^= h >>> 13;
h *= m;
h ^= h >>> 15;
return h;
}
}

View file

@ -32,17 +32,17 @@ package zutil;
*
*/
public interface OneInstance {
/**
* Checks if the application is already running
*
* @return True if the file is locked else false
*/
public boolean check();
/**
* Checks if the application is already running
*
* @return True if the file is locked else false
*/
public boolean check();
/**
* Locks the application so that another one can not run
*
* @return False if there are a error else true
*/
public boolean lockApp();
/**
* Locks the application so that another one can not run
*
* @return False if there are a error else true
*/
public boolean lockApp();
}

View file

@ -37,85 +37,85 @@ import java.nio.channels.OverlappingFileLockException;
* @author Ziver Koc
*/
public class OneInstanceFile implements OneInstance{
private File file;
private FileChannel channel;
private FileLock lock;
private File file;
private FileChannel channel;
private FileLock lock;
/**
* Creates a OneApp class
*
* @param filename The name of the file to be locked
*/
public OneInstanceFile(String filename){
this.file = new File(System.getProperty("user.home"), filename);
}
/**
* Creates a OneApp class
*
* @param filename The name of the file to be locked
*/
public OneInstanceFile(String filename){
this.file = new File(System.getProperty("user.home"), filename);
}
/**
* Checks if the file have already bean locked
*
* @return True if the file is locked else false
*/
public boolean check() {
boolean tmp = lockApp();
if( tmp ) closeLock();
return !tmp;
}
/**
* Checks if the file have already bean locked
*
* @return True if the file is locked else false
*/
public boolean check() {
boolean tmp = lockApp();
if( tmp ) closeLock();
return !tmp;
}
/**
* Locks the file
*
* @return False if there are a error else true
*/
public boolean lockApp() {
try {
channel = new RandomAccessFile(file, "rw").getChannel();
/**
* Locks the file
*
* @return False if there are a error else true
*/
public boolean lockApp() {
try {
channel = new RandomAccessFile(file, "rw").getChannel();
try {
lock = channel.tryLock();
}
catch (OverlappingFileLockException e) {
// already locked by this application
return false;
}
try {
lock = channel.tryLock();
}
catch (OverlappingFileLockException e) {
// already locked by this application
return false;
}
if (lock == null || lock.isShared()) {
// already locked by another application
return false;
}
if (lock == null || lock.isShared()) {
// already locked by another application
return false;
}
Runtime.getRuntime().addShutdownHook(new Thread() {
// destroy the lock when the JVM is closing
public void run() {
closeLock();
deleteFile();
}
});
return true;
}
catch (Exception e) {
closeLock();
return false;
}
}
Runtime.getRuntime().addShutdownHook(new Thread() {
// destroy the lock when the JVM is closing
public void run() {
closeLock();
deleteFile();
}
});
return true;
}
catch (Exception e) {
closeLock();
return false;
}
}
private void closeLock() {
try {
lock.release();
channel.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
private void closeLock() {
try {
lock.release();
channel.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
private void deleteFile() {
try {
file.delete();
}
catch (Exception e) {
e.printStackTrace();
}
}
private void deleteFile() {
try {
file.delete();
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -37,62 +37,62 @@ import java.net.Socket;
* @author Ziver Koc
*/
public class OneInstanceNetwork extends Thread implements OneInstance{
private int port;
/**
* Creates a One App objekt
*
* @param port The port to lock
*/
public OneInstanceNetwork(int port){
this.port = port;
}
/**
* Starts the port lock
*
* @return Always true
*/
public boolean lockApp(){
this.start();
return true;
}
/**
* he port lock thread
* should not be cald outside the class
*/
public void run() {
ServerSocket serverSocket = null;
Socket clientSocket = null;
try {
// Create the server socket
serverSocket = new ServerSocket(port, 1);
while (true) {
// Wait for a connection
clientSocket = serverSocket.accept();
clientSocket.close();
}
}
catch (IOException ioe) {
MultiPrintStream.out.println("Error in JustOneServer: " + ioe);
}
}
private int port;
/**
* Checks if the port is locked
*
* @return True if port is locked else false
*/
public boolean check() {
try {
Socket clientSocket = new Socket("localhost", port);
MultiPrintStream.out.println("Already running!!!");
clientSocket.close();
return true;
}
catch (Exception e) {
return false;
}
}
/**
* Creates a One App objekt
*
* @param port The port to lock
*/
public OneInstanceNetwork(int port){
this.port = port;
}
/**
* Starts the port lock
*
* @return Always true
*/
public boolean lockApp(){
this.start();
return true;
}
/**
* he port lock thread
* should not be cald outside the class
*/
public void run() {
ServerSocket serverSocket = null;
Socket clientSocket = null;
try {
// Create the server socket
serverSocket = new ServerSocket(port, 1);
while (true) {
// Wait for a connection
clientSocket = serverSocket.accept();
clientSocket.close();
}
}
catch (IOException ioe) {
MultiPrintStream.out.println("Error in JustOneServer: " + ioe);
}
}
/**
* Checks if the port is locked
*
* @return True if port is locked else false
*/
public boolean check() {
try {
Socket clientSocket = new Socket("localhost", port);
MultiPrintStream.out.println("Already running!!!");
clientSocket.close();
return true;
}
catch (Exception e) {
return false;
}
}
}

View file

@ -32,13 +32,13 @@ package zutil;
*
*/
public interface ProgressListener<S,D> {
/**
* This method is called when the progress is updated
*
* @param source is the source object of the progress
* @param info is some information from the source object
* @param percent is the progress of the object (0-100)
*/
public void progressUpdate(S source, D info, double percent);
/**
* This method is called when the progress is updated
*
* @param source is the source object of the progress
* @param info is some information from the source object
* @param percent is the progress of the object (0-100)
*/
public void progressUpdate(S source, D info, double percent);
}

View file

@ -38,104 +38,104 @@ import java.util.LinkedList;
*/
public class EuclideansAlgo {
/**
* Simple Test
* @param args
*/
public static void main(String[] args){
MultiPrintStream.out.println("*** Correct Answer: ");
MultiPrintStream.out.println("java.util.LinkedList{0, 2, 1, 1, 1, 4, 12, 102, 1, 1, 2, 3, 2, 2, 36}");
MultiPrintStream.out.println("GCD: 1");
MultiPrintStream.out.println("*** Integer:");
MultiPrintStream.out.dump(calcGenerators(60728973, 160523347));
MultiPrintStream.out.println("GCD: "+calc(60728973, 160523347));
MultiPrintStream.out.println("*** BigInteger: ");
MultiPrintStream.out.dump(calcGenerators(new BigInteger("60728973"), new BigInteger("160523347")));
MultiPrintStream.out.println("GCD: "+calc(new BigInteger("60728973"), new BigInteger("160523347")));
}
/**
* Runs the Euclidean algorithm on the two input
* values.
*
* @param a is the first integer
* @param b is the second integer
* @return a integer containing the GCD of the integers
*/
public static int calc(int a, int b){
int t;
while( b != 0 ){
t = b;
b = a % b;
a = t;
}
/**
* Simple Test
* @param args
*/
public static void main(String[] args){
MultiPrintStream.out.println("*** Correct Answer: ");
MultiPrintStream.out.println("java.util.LinkedList{0, 2, 1, 1, 1, 4, 12, 102, 1, 1, 2, 3, 2, 2, 36}");
MultiPrintStream.out.println("GCD: 1");
return a;
}
/**
* Runs the Euclidean algorithm on the two input
* values.
*
* @param a is the first BigInteger
* @param b is the second BigInteger
* @return a BigInteger containing the GCD of the BigIntegers
*/
public static BigInteger calc(BigInteger a, BigInteger b){
BigInteger t;
while( !b.equals(BigInteger.ZERO) ){
t = b;
b = a.mod( b );
a = t;
}
MultiPrintStream.out.println("*** Integer:");
MultiPrintStream.out.dump(calcGenerators(60728973, 160523347));
MultiPrintStream.out.println("GCD: "+calc(60728973, 160523347));
return a;
}
MultiPrintStream.out.println("*** BigInteger: ");
MultiPrintStream.out.dump(calcGenerators(new BigInteger("60728973"), new BigInteger("160523347")));
MultiPrintStream.out.println("GCD: "+calc(new BigInteger("60728973"), new BigInteger("160523347")));
}
/**
* Runs the Euclidean algorithm on the two input
* values to find the generators for the values.
*
* @param a is the first integer
* @param b is the second integer
* @return a list of integers that is generators for a and b
*/
public static LinkedList<Integer> calcGenerators(int a, int b){
LinkedList<Integer> list = new LinkedList<Integer>();
int t;
while( b != 0 ){
list.add( a/b );
t = b;
b = a % b;
a = t;
}
return list;
}
/**
* Runs the Euclidean algorithm on the two input
* values to find the generators for the values.
*
* @param a is the first BigInteger
* @param b is the second BigInteger
* @return a list of BigIntegers that is generators of a and b
*/
public static LinkedList<BigInteger> calcGenerators(BigInteger a, BigInteger b){
LinkedList<BigInteger> list = new LinkedList<BigInteger>();
BigInteger t;
while( !b.equals(BigInteger.ZERO) ){
list.add( new BigInteger("0").add( a.divide( b ) ) );
t = b;
b = a.mod( b );
a = t;
}
/**
* Runs the Euclidean algorithm on the two input
* values.
*
* @param a is the first integer
* @param b is the second integer
* @return a integer containing the GCD of the integers
*/
public static int calc(int a, int b){
int t;
while( b != 0 ){
t = b;
b = a % b;
a = t;
}
return list;
}
return a;
}
/**
* Runs the Euclidean algorithm on the two input
* values.
*
* @param a is the first BigInteger
* @param b is the second BigInteger
* @return a BigInteger containing the GCD of the BigIntegers
*/
public static BigInteger calc(BigInteger a, BigInteger b){
BigInteger t;
while( !b.equals(BigInteger.ZERO) ){
t = b;
b = a.mod( b );
a = t;
}
return a;
}
/**
* Runs the Euclidean algorithm on the two input
* values to find the generators for the values.
*
* @param a is the first integer
* @param b is the second integer
* @return a list of integers that is generators for a and b
*/
public static LinkedList<Integer> calcGenerators(int a, int b){
LinkedList<Integer> list = new LinkedList<Integer>();
int t;
while( b != 0 ){
list.add( a/b );
t = b;
b = a % b;
a = t;
}
return list;
}
/**
* Runs the Euclidean algorithm on the two input
* values to find the generators for the values.
*
* @param a is the first BigInteger
* @param b is the second BigInteger
* @return a list of BigIntegers that is generators of a and b
*/
public static LinkedList<BigInteger> calcGenerators(BigInteger a, BigInteger b){
LinkedList<BigInteger> list = new LinkedList<BigInteger>();
BigInteger t;
while( !b.equals(BigInteger.ZERO) ){
list.add( new BigInteger("0").add( a.divide( b ) ) );
t = b;
b = a.mod( b );
a = t;
}
return list;
}
}

View file

@ -36,76 +36,76 @@ import java.math.BigInteger;
* @see <a href="http://en.wikipedia.org/wiki/Shanks-Tonelli_algorithm">Wikipedia</a>
*/
public class ShanksTonelliAlgo {
public static BigInteger calc(BigInteger n, BigInteger p){
BigInteger nOrg = n;
BigInteger S = null, V, R, U, X;
BigInteger ONE = BigInteger.ONE;
BigInteger TWO = BigInteger.valueOf( 2 );
BigInteger Q = p.add( ONE ).divide( TWO );
public static BigInteger calc(BigInteger n, BigInteger p){
switch( p.mod( BigInteger.valueOf(4) ).intValue() ){
case 3:
S = n.pow( Q.divide( TWO ).intValue() ).mod( p );
break;
case 1:
S = ONE;
n = n.subtract( ONE );
while (n.divide( p ).compareTo( ONE ) == 0) {
S = S.add( ONE );
//n = (n-2s+1) mod p
n = n.subtract( TWO.multiply( S ) ).add( ONE ).mod( p );
if (n.compareTo( BigInteger.ZERO ) == 0){
return S;
}
}
Q = Q.divide( TWO );
V = ONE;
R = S;
U = ONE;
while (Q.compareTo( BigInteger.ZERO ) > 0) {
X = R.pow(2).subtract( n.multiply( U.pow(2) ) ).mod( p );
U = TWO.multiply( R ).multiply( U ).mod( p );
R = X;
if ( Q.testBit(0) ){
X = S.multiply( R ).subtract( n.multiply(V).multiply(U) ).mod( p );
V = V.multiply(R).add( S.multiply(U) ).mod( p );
S = X;
}
Q = Q.divide( TWO );
}
}
BigInteger nOrg = n;
BigInteger S = null, V, R, U, X;
BigInteger ONE = BigInteger.ONE;
BigInteger TWO = BigInteger.valueOf( 2 );
BigInteger Q = p.add( ONE ).divide( TWO );
if( S != null && S.multiply( S ).mod( p ).compareTo( nOrg ) != 0 ){
return null;
}
switch( p.mod( BigInteger.valueOf(4) ).intValue() ){
case 3:
S = n.pow( Q.divide( TWO ).intValue() ).mod( p );
break;
case 1:
S = ONE;
n = n.subtract( ONE );
while (n.divide( p ).compareTo( ONE ) == 0) {
S = S.add( ONE );
//n = (n-2s+1) mod p
n = n.subtract( TWO.multiply( S ) ).add( ONE ).mod( p );
if (n.compareTo( BigInteger.ZERO ) == 0){
return S;
}
}
Q = Q.divide( TWO );
V = ONE;
R = S;
U = ONE;
while (Q.compareTo( BigInteger.ZERO ) > 0) {
X = R.pow(2).subtract( n.multiply( U.pow(2) ) ).mod( p );
U = TWO.multiply( R ).multiply( U ).mod( p );
R = X;
if ( Q.testBit(0) ){
X = S.multiply( R ).subtract( n.multiply(V).multiply(U) ).mod( p );
V = V.multiply(R).add( S.multiply(U) ).mod( p );
S = X;
}
Q = Q.divide( TWO );
}
}
return S;
/*
//p-1 = Q*2^S
BigInteger S = null, Q = null, R = null, V = null, W = null;
if( S != null && S.multiply( S ).mod( p ).compareTo( nOrg ) != 0 ){
return null;
}
//Q = ( 2^S )/( 1-p );
p-1 = ( 2^S )/( 1-p ) * 2^S;
return S;
/*
// R = n^( (Q+1)/2 ) mod p
R = n.pow( Q.add(BigInteger.ONE).divide(BigInteger.valueOf(2)).intValue() ).mod( p );
// V = W^Q mod p
V = W.pow( Q.intValue() ).mod( p );
//p-1 = Q*2^S
BigInteger S = null, Q = null, R = null, V = null, W = null;
for(int i=S.intValue(); true ;){
while( true ){
i--;
// 1 = ( ( R^2 * n^-1 )^2^i ) mod p
if( ( R.pow(2).multiply( n.pow(-1) ) ).pow( (int)Math.pow(2, i) ).mod( p ).compareTo( BigInteger.ONE ) == 0 )
break;
}
//Q = ( 2^S )/( 1-p );
p-1 = ( 2^S )/( 1-p ) * 2^S;
if(i == 0) return R;
//R = ( RV^(2^(S-i-1)) ) mod p
else R = ( R.multiply( V.pow( (int)Math.pow( 2, S.intValue()-i-1) ) )).mod( p );
}
*/
}
// R = n^( (Q+1)/2 ) mod p
R = n.pow( Q.add(BigInteger.ONE).divide(BigInteger.valueOf(2)).intValue() ).mod( p );
// V = W^Q mod p
V = W.pow( Q.intValue() ).mod( p );
for(int i=S.intValue(); true ;){
while( true ){
i--;
// 1 = ( ( R^2 * n^-1 )^2^i ) mod p
if( ( R.pow(2).multiply( n.pow(-1) ) ).pow( (int)Math.pow(2, i) ).mod( p ).compareTo( BigInteger.ONE ) == 0 )
break;
}
if(i == 0) return R;
//R = ( RV^(2^(S-i-1)) ) mod p
else R = ( R.multiply( V.pow( (int)Math.pow( 2, S.intValue()-i-1) ) )).mod( p );
}
*/
}
}

View file

@ -38,56 +38,56 @@ import java.util.LinkedList;
*
*/
public class WienersAlgo {
/**
* Runs the Wieners algorithm for the given values.
*
* @param n is the first value
* @param e is the second value
* @return a BigInteger array of length two.
* First index is p and second is q.
* If no value was found then it returns null.
*/
public static BigInteger[] calc(BigInteger n, BigInteger e){
BigInteger[] ret = null;
LinkedList<BigInteger> gen = EuclideansAlgo.calcGenerators(e, n);
BigInteger c0 = BigInteger.ONE;
BigInteger c1 = gen.poll();
BigInteger d0 = BigInteger.ZERO;
BigInteger d1 = BigInteger.ONE;
BigInteger t, n1, g;
while(!gen.isEmpty()){
g = gen.poll();
t = c1;
c1 = g.multiply( c1 ).add( c0 );
c0 = t;
t = d1;
d1 = g.multiply( d1 ).add( d0 );
d0 = t;
// (d1*e-1) % c1 == 0
n1 = d1.multiply( e ).subtract( BigInteger.ONE );
if( n1.mod( c1 ).equals( BigInteger.ZERO ) ){
n1 = n1.divide( c1 );
// x^2 - ( n - n1 +1 )x + n = 0
ret = ZMath.pqFormula(
n.subtract( n1 ).add( BigInteger.ONE ).negate(),
n);
if(ret[0].compareTo( BigInteger.ZERO ) >= 0 &&
ret[1].compareTo( BigInteger.ZERO ) >= 0 &&
ret[0].multiply( ret[1] ).equals( n )){
return ret;
}
}
}
return null;
}
/**
* Runs the Wieners algorithm for the given values.
*
* @param n is the first value
* @param e is the second value
* @return a BigInteger array of length two.
* First index is p and second is q.
* If no value was found then it returns null.
*/
public static BigInteger[] calc(BigInteger n, BigInteger e){
BigInteger[] ret = null;
LinkedList<BigInteger> gen = EuclideansAlgo.calcGenerators(e, n);
BigInteger c0 = BigInteger.ONE;
BigInteger c1 = gen.poll();
BigInteger d0 = BigInteger.ZERO;
BigInteger d1 = BigInteger.ONE;
BigInteger t, n1, g;
while(!gen.isEmpty()){
g = gen.poll();
t = c1;
c1 = g.multiply( c1 ).add( c0 );
c0 = t;
t = d1;
d1 = g.multiply( d1 ).add( d0 );
d0 = t;
// (d1*e-1) % c1 == 0
n1 = d1.multiply( e ).subtract( BigInteger.ONE );
if( n1.mod( c1 ).equals( BigInteger.ZERO ) ){
n1 = n1.divide( c1 );
// x^2 - ( n - n1 +1 )x + n = 0
ret = ZMath.pqFormula(
n.subtract( n1 ).add( BigInteger.ONE ).negate(),
n);
if(ret[0].compareTo( BigInteger.ZERO ) >= 0 &&
ret[1].compareTo( BigInteger.ZERO ) >= 0 &&
ret[0].multiply( ret[1] ).equals( n )){
return ret;
}
}
}
return null;
}
}

View file

@ -30,42 +30,42 @@ import java.util.Queue;
/**
* A class that uses BFS to find a path
*
*
* @author Ziver
*/
public class BreadthFirstSearch implements PathFinder{
/**
* Returns the first path to the destination
*
* @param start is the start Node
* @param stop is the goal Node
* @return A list with the path
*/
public LinkedList<PathNode> find(PathNode start, PathNode stop){
Queue<PathNode> queue = new LinkedList<PathNode>();
HashSet<PathNode> visited = new HashSet<PathNode>();
queue.add(start);
visited.add( start );
PathNode tmp;
while(!queue.isEmpty()){
tmp = queue.poll();
for(PathNode next : tmp.getNeighbors()){
if(!visited.contains( next ) && tmp.getNeighborCost(next) > 0){
queue.add(next);
visited.add( next );
next.setParentNeighbor(tmp);
if(next.equals(stop)){
return stop.traversTo(start);
}
}
}
}
return new LinkedList<PathNode>();
}
/**
* Returns the first path to the destination
*
* @param start is the start Node
* @param stop is the goal Node
* @return A list with the path
*/
public LinkedList<PathNode> find(PathNode start, PathNode stop){
Queue<PathNode> queue = new LinkedList<PathNode>();
HashSet<PathNode> visited = new HashSet<PathNode>();
queue.add(start);
visited.add( start );
PathNode tmp;
while(!queue.isEmpty()){
tmp = queue.poll();
for(PathNode next : tmp.getNeighbors()){
if(!visited.contains( next ) && tmp.getNeighborCost(next) > 0){
queue.add(next);
visited.add( next );
next.setParentNeighbor(tmp);
if(next.equals(stop)){
return stop.traversTo(start);
}
}
}
}
return new LinkedList<>();
}
}

View file

@ -33,42 +33,42 @@ import java.util.LinkedList;
* @author Ziver
*/
public class DepthFirstSearch {
private HashSet<PathNode> visited = new HashSet<PathNode>();
private HashSet<PathNode> visited = new HashSet<PathNode>();
/**
* Returns the first path to the destination
*
* @param start Start Node
* @param stop Stop Node
* @return A list with the path
*/
public LinkedList<PathNode> find(PathNode start, PathNode stop){
visited.clear();
PathNode node = dfs(start, stop);
return node.traversTo( start );
}
/**
* Returns the first path to the destination
*
* @param start Start Node
* @param stop Stop Node
* @return A list with the path
*/
public LinkedList<PathNode> find(PathNode start, PathNode stop){
visited.clear();
PathNode node = dfs(start, stop);
return node.traversTo( start );
}
/**
* The DepthFirstSearch algorithm
* @param node The node to search from
* @return The stop PathNode if a path was found else null
*/
private PathNode dfs(PathNode node, PathNode stop){
visited.add( node );
if(node.equals(stop)){
return node;
}
/**
* The DepthFirstSearch algorithm
* @param node The node to search from
* @return The stop PathNode if a path was found else null
*/
private PathNode dfs(PathNode node, PathNode stop){
visited.add( node );
if(node.equals(stop)){
return node;
}
for(PathNode next : node.getNeighbors()){
if(!visited.contains( next ) && node.getNeighborCost(next) > 0){
next.setParentNeighbor(node);
PathNode tmp = dfs(next, stop);
if(tmp != null){
return tmp;
}
}
}
return null;
}
for(PathNode next : node.getNeighbors()){
if(!visited.contains( next ) && node.getNeighborCost(next) > 0){
next.setParentNeighbor(node);
PathNode tmp = dfs(next, stop);
if(tmp != null){
return tmp;
}
}
}
return null;
}
}

View file

@ -25,117 +25,117 @@
package zutil.algo.path;
public class DynamicProgramming {
public static char[][] words = new char[][]{
"bibba".toCharArray(),
"bitas".toCharArray(),
"brott".toCharArray(),
"bl<EFBFBD>ja".toCharArray(),
"boson".toCharArray()
};
public static char[][] words = new char[][]{
"bibba".toCharArray(),
"bitas".toCharArray(),
"brott".toCharArray(),
"bl<EFBFBD>ja".toCharArray(),
"boson".toCharArray()
};
public static void main(String[] args){
new DynamicProgramming().search();
}
/*
public static void main(String[] args){
new DynamicProgramming().search();
}
/*
int search(words[][][])
matrix[][][] = 0
shortest = -1
for w=0->length(words)
for y=0->length(words)
for x=0->length(words)
// f<EFBFBD>rsta raden i matrisen
if y == 0
// finns f<EFBFBD>rsta bokstaven i r<EFBFBD>tt position i f<EFBFBD>rsta ordet?
if words[0][x] != words[w][0]
matrix[w][y][x] = -1
else
matrix[w][y][x] = 0
else
// om f<EFBFBD>reg<EFBFBD>ende <EFBFBD>r negativ s<EFBFBD>tt nuvarande till negativ
if matrix[w][y-1][x] < 0
matrix[w][y-1][x] = -1
// h<EFBFBD>r s<EFBFBD> h<EFBFBD>nder det riktiga i algoritmen
else
tmp = minstaForskjutning(words[y], words[w][y], x)
if tmp >= 0
matrix[w][y][x] = matrix[w][y-1][x] + tmp
else
matrix[w][y][x] = -1
// kolla om det <EFBFBD>r sista raden i matrisen
if y == length(matrix)
if (tmp < shortest || shortest < 0) && tmp >= 0
shortest = tmp;
return shortest
matrix[][][] = 0
shortest = -1
for w=0->length(words)
for y=0->length(words)
for x=0->length(words)
// f<EFBFBD>rsta raden i matrisen
if y == 0
// finns f<EFBFBD>rsta bokstaven i r<EFBFBD>tt position i f<EFBFBD>rsta ordet?
if words[0][x] != words[w][0]
matrix[w][y][x] = -1
else
matrix[w][y][x] = 0
else
// om f<EFBFBD>reg<EFBFBD>ende <EFBFBD>r negativ s<EFBFBD>tt nuvarande till negativ
if matrix[w][y-1][x] < 0
matrix[w][y-1][x] = -1
// h<EFBFBD>r s<EFBFBD> h<EFBFBD>nder det riktiga i algoritmen
else
tmp = minstaForskjutning(words[y], words[w][y], x)
if tmp >= 0
matrix[w][y][x] = matrix[w][y-1][x] + tmp
else
matrix[w][y][x] = -1
// kolla om det <EFBFBD>r sista raden i matrisen
if y == length(matrix)
if (tmp < shortest || shortest < 0) && tmp >= 0
shortest = tmp;
return shortest
int minstaForskjutning(word[], find, index){
minsta = -1
for i=0->length(word)
if word[i] == cfind && (abs(index-i) < minsta || minsta < 0)
minsta = abs(index-i)
return minsta
*/
minsta = -1
for i=0->length(word)
if word[i] == cfind && (abs(index-i) < minsta || minsta < 0)
minsta = abs(index-i)
public int search(){
int[][][] matrix = new int[words.length][words.length][words.length];
int shortest = -1;
return minsta
for(int w=0; w<words.length ;w++){ //lodr<EFBFBD>ta ordet
System.out.print("\n\n"+new String(words[w])+"\n ");
for(int y=0; y<words.length ;y++){ // v<EFBFBD>gr<EFBFBD>ta ordet
System.out.print("\n"+ new String(words[y])+": ");
for(int x=0; x<words.length ;x++){ // psition i y
// f<EFBFBD>rsta v<EFBFBD>gr<EFBFBD>ta ordet
if(y == 0){
if(words[0][x] != words[w][0]){
matrix[w][y][x] = -1;
}
else{
matrix[w][y][x] = 0;
}
}
//resten av de v<EFBFBD>gr<EFBFBD>ta orden
else{
if(matrix[w][y-1][x] < 0){
matrix[w][y][x] = -1;
}
else{
int tmp = minstaForskjutning(words[y], words[w][y], x);
if(tmp >= 0){
matrix[w][y][x] = matrix[w][y-1][x] + tmp;
}
else{
matrix[w][y][x] = -1;
}
}
}
if(y == words.length-1){
int tmp = matrix[w][y][x];
if((tmp<shortest || shortest<0)
&& tmp>= 0){
shortest = tmp;
}
}
System.out.print(" "+matrix[w][y][x]);
}
}
}
*/
System.out.println("\n\nKortaste f<>rflyttningen: "+shortest);
return shortest;
}
public int search(){
int[][][] matrix = new int[words.length][words.length][words.length];
int shortest = -1;
private int minstaForskjutning(char[] word, char cfind, int index){
int minsta = -1;
for(int i=0; i<word.length ;i++){
if(word[i] == cfind && (Math.abs(index-i)<minsta || minsta<0)){
minsta = Math.abs(index-i);
}
}
return minsta;
}
for(int w=0; w<words.length ;w++){ //lodr<EFBFBD>ta ordet
System.out.print("\n\n"+new String(words[w])+"\n ");
for(int y=0; y<words.length ;y++){ // v<EFBFBD>gr<EFBFBD>ta ordet
System.out.print("\n"+ new String(words[y])+": ");
for(int x=0; x<words.length ;x++){ // psition i y
// f<EFBFBD>rsta v<EFBFBD>gr<EFBFBD>ta ordet
if(y == 0){
if(words[0][x] != words[w][0]){
matrix[w][y][x] = -1;
}
else{
matrix[w][y][x] = 0;
}
}
//resten av de v<EFBFBD>gr<EFBFBD>ta orden
else{
if(matrix[w][y-1][x] < 0){
matrix[w][y][x] = -1;
}
else{
int tmp = minstaForskjutning(words[y], words[w][y], x);
if(tmp >= 0){
matrix[w][y][x] = matrix[w][y-1][x] + tmp;
}
else{
matrix[w][y][x] = -1;
}
}
}
if(y == words.length-1){
int tmp = matrix[w][y][x];
if((tmp<shortest || shortest<0)
&& tmp>= 0){
shortest = tmp;
}
}
System.out.print(" "+matrix[w][y][x]);
}
}
}
System.out.println("\n\nKortaste f<>rflyttningen: "+shortest);
return shortest;
}
private int minstaForskjutning(char[] word, char cfind, int index){
int minsta = -1;
for(int i=0; i<word.length ;i++){
if(word[i] == cfind && (Math.abs(index-i)<minsta || minsta<0)){
minsta = Math.abs(index-i);
}
}
return minsta;
}
}

View file

@ -33,13 +33,13 @@ import java.util.LinkedList;
*/
public interface PathFinder {
/**
* Starts the search for the path from the start
* node to the goal.
*
* @param start is the starting point of the search
* @param goal is the search goal
* @return a LinkedList of the path, empty list if no path was found
*/
public LinkedList<PathNode> find(PathNode start, PathNode goal);
/**
* Starts the search for the path from the start
* node to the goal.
*
* @param start is the starting point of the search
* @param goal is the search goal
* @return a LinkedList of the path, empty list if no path was found
*/
public LinkedList<PathNode> find(PathNode start, PathNode goal);
}

View file

@ -29,32 +29,32 @@ import java.util.LinkedList;
public interface PathNode {
/**
* @return an Iterator with all its neighbors
*/
public Iterable<PathNode> getNeighbors();
/**
* @param neighbor is the neighbor
* @return the cost to the neighbor
*/
public int getNeighborCost(PathNode neighbor);
/**
* Sets the parent node to this one
*/
public void setParentNeighbor(PathNode parent);
/**
* @return the parent node
*/
public PathNode getParentNeighbor();
/**
* Traverses the parent tree and returns the path.
*
* @param goal is the node to reach
* @return the path to the goal, empty list if there is no goal
*/
public LinkedList<PathNode> traversTo(PathNode goal);
/**
* @return an Iterator with all its neighbors
*/
public Iterable<PathNode> getNeighbors();
/**
* @param neighbor is the neighbor
* @return the cost to the neighbor
*/
public int getNeighborCost(PathNode neighbor);
/**
* Sets the parent node to this one
*/
public void setParentNeighbor(PathNode parent);
/**
* @return the parent node
*/
public PathNode getParentNeighbor();
/**
* Traverses the parent tree and returns the path.
*
* @param goal is the node to reach
* @return the path to the goal, empty list if there is no goal
*/
public LinkedList<PathNode> traversTo(PathNode goal);
}

View file

@ -33,32 +33,32 @@ import java.util.LinkedList;
*
*/
public class StandardPathNode implements PathNode{
private HashMap<PathNode,Integer> neighbors;
private PathNode parent;
public StandardPathNode(){
neighbors = new HashMap<PathNode,Integer>();
}
private HashMap<PathNode,Integer> neighbors;
private PathNode parent;
public int getNeighborCost(PathNode neighbor) {
return neighbors.get(neighbor);
}
public StandardPathNode(){
neighbors = new HashMap<PathNode,Integer>();
}
public Iterable<PathNode> getNeighbors() {
return neighbors.keySet();
}
public int getNeighborCost(PathNode neighbor) {
return neighbors.get(neighbor);
}
public PathNode getParentNeighbor() {
return parent;
}
public Iterable<PathNode> getNeighbors() {
return neighbors.keySet();
}
public void setParentNeighbor(PathNode parent) {
this.parent = parent;
}
public PathNode getParentNeighbor() {
return parent;
}
public LinkedList<PathNode> traversTo(PathNode goal) {
LinkedList<PathNode> path = new LinkedList<PathNode>();
PathNode current = this;
public void setParentNeighbor(PathNode parent) {
this.parent = parent;
}
public LinkedList<PathNode> traversTo(PathNode goal) {
LinkedList<PathNode> path = new LinkedList<PathNode>();
PathNode current = this;
while(current != null){
path.addFirst(current);
current = current.getParentNeighbor();
@ -68,6 +68,6 @@ public class StandardPathNode implements PathNode{
}
}
return new LinkedList<PathNode>();
}
}
}

View file

@ -36,57 +36,57 @@ import zutil.algo.sort.sortable.SortableDataList;
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public class QuickSelect {
public static Object find(SortableDataList list, int k){
return find(list, k, 0, list.size()-1);
}
/*
function select(list, k, left, right)
select a pivot value list[pivotIndex]
pivotNewIndex := partition(list, left, right, pivotIndex)
if k = pivotNewIndex
return list[k]
else if k < pivotNewIndex
return select(list, k, left, pivotNewIndex-1)
else
return select(list, k, pivotNewIndex+1, right)
*/
public static Object find(SortableDataList list, int k, int left, int right){
// select a pivot
int pivot = right/2;
int newPivot = partition(list, left, right, pivot);
if(k == newPivot)
return list.get(k);
else if(k < newPivot)
return find(list, k, left, newPivot-1);
else
return find(list, k, newPivot+1, right);
}
/*
function partition(list, left, right, pivotIndex)
pivotValue := list[pivotIndex]
swap list[pivotIndex] and list[right] // Move pivot to end
storeIndex := left
for i from left to right-1
if list[i] < pivotValue
swap list[storeIndex] and list[i]
storeIndex := storeIndex + 1
swap list[right] and list[storeIndex] // Move pivot to its final place
return storeIndex
*/
private static int partition(SortableDataList list, int left, int right, int pivot){
Object pivotValue = list.get(pivot);
list.swap(pivot, right);
int storeIndex = left;
for(int i=left; i<right ;i++){
if(list.compare(i, pivotValue) < 0){
list.swap(storeIndex, i);
storeIndex = storeIndex+1;
}
}
list.swap(right, storeIndex);
return storeIndex;
}
public static Object find(SortableDataList list, int k){
return find(list, k, 0, list.size()-1);
}
/*
function select(list, k, left, right)
select a pivot value list[pivotIndex]
pivotNewIndex := partition(list, left, right, pivotIndex)
if k = pivotNewIndex
return list[k]
else if k < pivotNewIndex
return select(list, k, left, pivotNewIndex-1)
else
return select(list, k, pivotNewIndex+1, right)
*/
public static Object find(SortableDataList list, int k, int left, int right){
// select a pivot
int pivot = right/2;
int newPivot = partition(list, left, right, pivot);
if(k == newPivot)
return list.get(k);
else if(k < newPivot)
return find(list, k, left, newPivot-1);
else
return find(list, k, newPivot+1, right);
}
/*
function partition(list, left, right, pivotIndex)
pivotValue := list[pivotIndex]
swap list[pivotIndex] and list[right] // Move pivot to end
storeIndex := left
for i from left to right-1
if list[i] < pivotValue
swap list[storeIndex] and list[i]
storeIndex := storeIndex + 1
swap list[right] and list[storeIndex] // Move pivot to its final place
return storeIndex
*/
private static int partition(SortableDataList list, int left, int right, int pivot){
Object pivotValue = list.get(pivot);
list.swap(pivot, right);
int storeIndex = left;
for(int i=left; i<right ;i++){
if(list.compare(i, pivotValue) < 0){
list.swap(storeIndex, i);
storeIndex = storeIndex+1;
}
}
list.swap(right, storeIndex);
return storeIndex;
}
}

View file

@ -37,233 +37,233 @@ import java.util.LinkedList;
* @author Ziver
*/
public class ExternalSort {
public static int CHUNK_SIZE = 100000;
public static int CHUNK_SIZE = 100000;
private BufferedReader in;
private File sortedFile;
private BufferedReader in;
private File sortedFile;
/**
* Creates a ExternalSort object that sort a big file
* with minimal use of ram
*
* @param orgFile File to sort
* @param sortedFile The sorted file
* @throws FileNotFoundException
*/
public ExternalSort(File orgFile, File sortedFile) throws FileNotFoundException{
in = new BufferedReader(new FileReader(orgFile));
this.sortedFile = sortedFile;
}
/**
* Creates a ExternalSort object that sort a big file
* with minimal use of ram
*
* @param orgFile File to sort
* @param sortedFile The sorted file
* @param chunk The chunk size
* @throws FileNotFoundException
*/
public ExternalSort(File orgFile, File sortedFile, int chunk) throws FileNotFoundException{
in = new BufferedReader(new FileReader(orgFile));
this.sortedFile = sortedFile;
CHUNK_SIZE = chunk;
}
/**
* Creates a ExternalSort object that sort a big file
* with minimal use of ram
*
* @param orgFile File to sort
* @param sortedFile The sorted file
* @throws FileNotFoundException
*/
public ExternalSort(File orgFile, File sortedFile) throws FileNotFoundException{
in = new BufferedReader(new FileReader(orgFile));
this.sortedFile = sortedFile;
}
/**
* Sorts the given file
*
* @throws IOException Some kind of error
*/
public void sort() throws IOException{
// sorting the chunks
LinkedList<File> chunkFiles = sortChunks();
/**
* Creates a ExternalSort object that sort a big file
* with minimal use of ram
*
* @param orgFile File to sort
* @param sortedFile The sorted file
* @param chunk The chunk size
* @throws FileNotFoundException
*/
public ExternalSort(File orgFile, File sortedFile, int chunk) throws FileNotFoundException{
in = new BufferedReader(new FileReader(orgFile));
this.sortedFile = sortedFile;
CHUNK_SIZE = chunk;
}
//merging the chunks
mergeFiles(chunkFiles);
/**
* Sorts the given file
*
* @throws IOException Some kind of error
*/
public void sort() throws IOException{
// sorting the chunks
LinkedList<File> chunkFiles = sortChunks();
//removing the chunks
removeFiles(chunkFiles);
}
//merging the chunks
mergeFiles(chunkFiles);
/**
* Merges all the files to one
* @param files
*/
private void mergeFiles(LinkedList<File> files){
try {
BufferedReader[] chunkReader = new BufferedReader[files.size()];
String[] rows = new String[files.size()];
BufferedWriter out = new BufferedWriter(new FileWriter(sortedFile));
//removing the chunks
removeFiles(chunkFiles);
}
boolean someFileStillHasRows = false;
/**
* Merges all the files to one
* @param files
*/
private void mergeFiles(LinkedList<File> files){
try {
BufferedReader[] chunkReader = new BufferedReader[files.size()];
String[] rows = new String[files.size()];
BufferedWriter out = new BufferedWriter(new FileWriter(sortedFile));
for (int i=0; i<files.size(); i++){
chunkReader[i] = new BufferedReader(new FileReader(files.get(i)));
boolean someFileStillHasRows = false;
// get the first row
String line = chunkReader[i].readLine();
if (line != null){
rows[i] = line;
someFileStillHasRows = true;
}
else{
rows[i] = null;
}
for (int i=0; i<files.size(); i++){
chunkReader[i] = new BufferedReader(new FileReader(files.get(i)));
}
// get the first row
String line = chunkReader[i].readLine();
if (line != null){
rows[i] = line;
someFileStillHasRows = true;
}
else{
rows[i] = null;
}
String row;
while (someFileStillHasRows){
String min;
int minIndex = 0;
}
row = rows[0];
if (row!=null) {
min = row;
minIndex = 0;
}
else {
min = null;
minIndex = -1;
}
String row;
while (someFileStillHasRows){
String min;
int minIndex = 0;
// check which one is minimum
for(int i=1; i<rows.length ;i++){
row = rows[i];
if (min!=null) {
if(row!=null && row.compareTo(min) < 0){
minIndex = i;
min = row;
}
}
else{
if(row!=null){
min = row;
minIndex = i;
}
}
}
row = rows[0];
if (row!=null) {
min = row;
minIndex = 0;
}
else {
min = null;
minIndex = -1;
}
if (minIndex < 0) {
someFileStillHasRows = false;
}
else{
// write to the sorted file
out.append(rows[minIndex]);
out.newLine();
// check which one is minimum
for(int i=1; i<rows.length ;i++){
row = rows[i];
if (min!=null) {
if(row!=null && row.compareTo(min) < 0){
minIndex = i;
min = row;
}
}
else{
if(row!=null){
min = row;
minIndex = i;
}
}
}
// get another row from the file that had the min
String line = chunkReader[minIndex].readLine();
if (line != null){
rows[minIndex] = line;
}
else{
rows[minIndex] = null;
}
}
// check if one still has rows
someFileStillHasRows = false;
for(int i=0; i<rows.length ; i++){
if(rows[i] != null){
if (minIndex < 0){
throw(new IOException("Error sorting!!!"));
}
someFileStillHasRows = true;
break;
}
}
if (minIndex < 0) {
someFileStillHasRows = false;
}
else{
// write to the sorted file
out.append(rows[minIndex]);
out.newLine();
// check the actual files one more time
if (!someFileStillHasRows){
//write the last one not covered above
for(int i=0; i<rows.length ; i++){
if (rows[i] == null){
String line = chunkReader[i].readLine();
if (line != null){
someFileStillHasRows=true;
rows[i] = line;
}
}
}
}
}
// close all the files
out.close();
for(int i=0; i<chunkReader.length ; i++){
chunkReader[i].close();
}
}
catch (Exception ex){
ex.printStackTrace();
System.exit(-1);
}
}
// get another row from the file that had the min
String line = chunkReader[minIndex].readLine();
if (line != null){
rows[minIndex] = line;
}
else{
rows[minIndex] = null;
}
}
/**
* Sorts the chunk files and returns a LinkedList
* with all the files
* @return A linkedList with the files
* @throws IOException Some kind of error
*/
private LinkedList<File> sortChunks() throws IOException{
LinkedList<File> chunkFiles = new LinkedList<File>();
LinkedList<String> chunk = new LinkedList<String>();
do{
chunk = readChunk(in);
// check if one still has rows
someFileStillHasRows = false;
for(int i=0; i<rows.length ; i++){
if(rows[i] != null){
if (minIndex < 0){
throw(new IOException("Error sorting!!!"));
}
someFileStillHasRows = true;
break;
}
}
//QuickSort.sort(new SortableLinkedList(chunk));
Collections.sort(chunk);
// check the actual files one more time
if (!someFileStillHasRows){
//write the last one not covered above
for(int i=0; i<rows.length ; i++){
if (rows[i] == null){
String line = chunkReader[i].readLine();
if (line != null){
someFileStillHasRows=true;
rows[i] = line;
}
}
}
}
}
// close all the files
out.close();
for(int i=0; i<chunkReader.length ; i++){
chunkReader[i].close();
}
}
catch (Exception ex){
ex.printStackTrace();
System.exit(-1);
}
}
File file = new File("extsort"+chunkFiles.size()+".txt");
chunkFiles.add(file);
writeChunk(chunk,file);
}while(!chunk.isEmpty());
/**
* Sorts the chunk files and returns a LinkedList
* with all the files
* @return A linkedList with the files
* @throws IOException Some kind of error
*/
private LinkedList<File> sortChunks() throws IOException{
LinkedList<File> chunkFiles = new LinkedList<File>();
LinkedList<String> chunk = new LinkedList<String>();
do{
chunk = readChunk(in);
return chunkFiles;
}
//QuickSort.sort(new SortableLinkedList(chunk));
Collections.sort(chunk);
/**
* Reads in a chunk of rows into a LinkedList
*
* @param list The list to populate
* @param in The BufferedReader to read from
* @return The LinkeList with the chunk
* @throws IOException Some kind of error
*/
private LinkedList<String> readChunk(BufferedReader in) throws IOException{
LinkedList<String> list = new LinkedList<String>();
String tmp;
for(int i=0; i<CHUNK_SIZE ;i++){
tmp = in.readLine();
if(tmp == null) break;
list.add(tmp);
}
return list;
}
File file = new File("extsort"+chunkFiles.size()+".txt");
chunkFiles.add(file);
writeChunk(chunk,file);
}while(!chunk.isEmpty());
/**
* Writs a chunk of strings to a file
*
* @param list The list to write down
* @param file The file to write to
* @throws IOException Some kind of error
*/
private void writeChunk(LinkedList<String> list, File file) throws IOException{
BufferedWriter out = new BufferedWriter(new FileWriter(file));
Iterator<String> it = list.iterator();
while(it.hasNext()){
out.write(it.next());
out.newLine();
}
out.close();
}
return chunkFiles;
}
private void removeFiles(LinkedList<File> list){
Iterator<File> it = list.iterator();
while(it.hasNext()){
it.next().delete();
}
}
/**
* Reads in a chunk of rows into a LinkedList
*
* @param list The list to populate
* @param in The BufferedReader to read from
* @return The LinkeList with the chunk
* @throws IOException Some kind of error
*/
private LinkedList<String> readChunk(BufferedReader in) throws IOException{
LinkedList<String> list = new LinkedList<String>();
String tmp;
for(int i=0; i<CHUNK_SIZE ;i++){
tmp = in.readLine();
if(tmp == null) break;
list.add(tmp);
}
return list;
}
/**
* Writs a chunk of strings to a file
*
* @param list The list to write down
* @param file The file to write to
* @throws IOException Some kind of error
*/
private void writeChunk(LinkedList<String> list, File file) throws IOException{
BufferedWriter out = new BufferedWriter(new FileWriter(file));
Iterator<String> it = list.iterator();
while(it.hasNext()){
out.write(it.next());
out.newLine();
}
out.close();
}
private void removeFiles(LinkedList<File> list){
Iterator<File> it = list.iterator();
while(it.hasNext()){
it.next().delete();
}
}
}

View file

@ -29,131 +29,131 @@ import zutil.algo.sort.sortable.SortableDataList;
public class MergeSort{
/**
* Sorts the given list with Merge sort
*
* @param list is the list to sort
*/
public static void sort(int[] list){
if(list == null)
return;
sort(list, 0, list.length);
}
/**
* Sorts the given list with Merge sort
*
* @param list is the list to sort
*/
public static void sort(int[] list){
if(list == null)
return;
/**
* This method is the array splitting method
* that recursively splits the array in two.
*
* @param list is the list to sort
* @param start is the starting index of the sub list
* @param stop is the end index of the sub list
*/
protected static void sort(int[] list, int start, int stop){
if(stop-start <= 1) return;
sort(list, 0, list.length);
}
int pivot = start+(stop-start)/2;
sort(list, start, pivot);
sort(list, pivot, stop);
/**
* This method is the array splitting method
* that recursively splits the array in two.
*
* @param list is the list to sort
* @param start is the starting index of the sub list
* @param stop is the end index of the sub list
*/
protected static void sort(int[] list, int start, int stop){
if(stop-start <= 1) return;
merge(list, start, stop, pivot);
}
int pivot = start+(stop-start)/2;
sort(list, start, pivot);
sort(list, pivot, stop);
/**
* This method is the merger, after the array
* has been split this method will merge the
* two parts of the array and sort it.
*
* @param list is the list to merge
* @param start is the start of the first sublist
* @param stop is the end of the second sublist
* @param pivot is the end index for the first list and the beginning of the second.
*/
protected static void merge(int[] list, int start, int stop, int pivot){
int length = pivot-start;
int[] tmp = new int[stop-start];
merge(list, start, stop, pivot);
}
for(int i=0; i<tmp.length ;++i){
tmp[i] = list[start+i];
}
/**
* This method is the merger, after the array
* has been split this method will merge the
* two parts of the array and sort it.
*
* @param list is the list to merge
* @param start is the start of the first sublist
* @param stop is the end of the second sublist
* @param pivot is the end index for the first list and the beginning of the second.
*/
protected static void merge(int[] list, int start, int stop, int pivot){
int length = pivot-start;
int[] tmp = new int[stop-start];
int index1 = 0;
int index2 = length;
for(int i=start; i<stop ;++i){
if( index2 < stop-start && (index1 >= length || tmp[index1] > tmp[index2]) ){
list[i] = tmp[index2];
++index2;
}
else {
list[i] = tmp[index1];
++index1;
}
}
}
/**
* Sorts the given list with Merge sort,
* this is slower than the one with int[] array
*
* @param list is the list to sort
*/
public static void sort(SortableDataList<?> list){
if(list == null)
return;
sort(list, 0, list.size());
}
for(int i=0; i<tmp.length ;++i){
tmp[i] = list[start+i];
}
/**
* This method is the array splitting method
* that recursively splits the array in two.
*
* @param list is the list to sort
* @param start is the starting index of the sub list
* @param stop is the end index of the sub list
*/
protected static void sort(SortableDataList<?> list, int start, int stop){
if(stop-start <= 1) return;
int index1 = 0;
int index2 = length;
for(int i=start; i<stop ;++i){
if( index2 < stop-start && (index1 >= length || tmp[index1] > tmp[index2]) ){
list[i] = tmp[index2];
++index2;
}
else {
list[i] = tmp[index1];
++index1;
}
}
}
int pivot = start+(stop-start)/2;
sort(list, start, pivot);
sort(list, pivot, stop);
merge(list, start, stop, pivot);
}
/**
* Sorts the given list with Merge sort,
* this is slower than the one with int[] array
*
* @param list is the list to sort
*/
public static void sort(SortableDataList<?> list){
if(list == null)
return;
/**
* This method is the merger, after the array
* has been split this method will merge the
* two parts of the array and sort it.
* @param <T>
*
* @param list is the list to merge
* @param start is the start of the first sublist
* @param stop is the end of the second sublist
* @param pivot is the end index for the first list and the beginning of the second.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
protected static <T> void merge(SortableDataList<T> list, int start, int stop, int pivot){
int length = pivot-start;
Object[] tmp = new Object[stop-start];
sort(list, 0, list.size());
}
for(int i=0; i<tmp.length ;++i){
tmp[i] = list.get( start+i );
}
/**
* This method is the array splitting method
* that recursively splits the array in two.
*
* @param list is the list to sort
* @param start is the starting index of the sub list
* @param stop is the end index of the sub list
*/
protected static void sort(SortableDataList<?> list, int start, int stop){
if(stop-start <= 1) return;
int index1 = 0;
int index2 = length;
for(int i=start; i<stop ;++i){
if( index2 < stop-start && (index1 >= length || ((Comparable)tmp[index1]).compareTo(tmp[index2]) > 0 )){
list.set(i, (T)tmp[index2]);
++index2;
}
else {
list.set(i, (T)tmp[index1]);
++index1;
}
}
}
int pivot = start+(stop-start)/2;
sort(list, start, pivot);
sort(list, pivot, stop);
merge(list, start, stop, pivot);
}
/**
* This method is the merger, after the array
* has been split this method will merge the
* two parts of the array and sort it.
* @param <T>
*
* @param list is the list to merge
* @param start is the start of the first sublist
* @param stop is the end of the second sublist
* @param pivot is the end index for the first list and the beginning of the second.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
protected static <T> void merge(SortableDataList<T> list, int start, int stop, int pivot){
int length = pivot-start;
Object[] tmp = new Object[stop-start];
for(int i=0; i<tmp.length ;++i){
tmp[i] = list.get( start+i );
}
int index1 = 0;
int index2 = length;
for(int i=start; i<stop ;++i){
if( index2 < stop-start && (index1 >= length || ((Comparable)tmp[index1]).compareTo(tmp[index2]) > 0 )){
list.set(i, (T)tmp[index2]);
++index2;
}
else {
list.set(i, (T)tmp[index1]);
++index1;
}
}
}
}

View file

@ -33,17 +33,17 @@ import zutil.algo.sort.sortable.SortableDataList;
* @author Ziver
*/
public class QuickSort{
public static final int RANDOM_PIVOT = 0;
public static final int MEDIAN_PIVOT = 1;
public static final int MIDDLE_PIVOT = 2;
public static final int RANDOM_PIVOT = 0;
public static final int MEDIAN_PIVOT = 1;
public static final int MIDDLE_PIVOT = 2;
/**
* Sort the elements in ascending order using Quicksort.
*
* @param list is the list to sort.
*/
public static void sort(SortableDataList<?> list){
sort(list, 0, list.size()-1, MIDDLE_PIVOT, true);
public static void sort(SortableDataList<?> list){
sort(list, 0, list.size()-1, MIDDLE_PIVOT, true);
}
/**
@ -53,10 +53,10 @@ public class QuickSort{
* @param type is the type of pivot
* @param insert is if insertion sort will be used
*/
public static void sort(SortableDataList<?> list, int type, boolean insert){
sort(list, 0, list.size()-1, type, insert);
public static void sort(SortableDataList<?> list, int type, boolean insert){
sort(list, 0, list.size()-1, type, insert);
}
/**
* Sort the elements in ascending order using Quicksort.
* Reference: http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/quick/quicken.htm
@ -67,59 +67,59 @@ public class QuickSort{
* @param stop is the index to stop
* @param type is the type of pivot to use
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void sort(SortableDataList list, int start, int stop, int type, boolean insertionSort){
if(stop-start <= 15 && insertionSort){
SimpleSort.insertionSort( list, start, stop);
}
int pivotIndex = pivot(list,start,stop,type);
Object pivot = list.get(pivotIndex);
int left=start, right=stop;
do{
while(list.compare(left, pivot) < 0){
left++;
}
while(list.compare(right, pivot) > 0){
right--;
}
if(left <= right){
list.swap(left, right);
left++;
right--;
}
}while(left <= right);
if(start < right){
sort(list, start, right, type, insertionSort);
}
if(left < stop){
sort(list, left, stop, type, insertionSort);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void sort(SortableDataList list, int start, int stop, int type, boolean insertionSort){
if(stop-start <= 15 && insertionSort){
SimpleSort.insertionSort( list, start, stop);
}
int pivotIndex = pivot(list,start,stop,type);
Object pivot = list.get(pivotIndex);
int left=start, right=stop;
}
do{
while(list.compare(left, pivot) < 0){
left++;
}
while(list.compare(right, pivot) > 0){
right--;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static int pivot(SortableDataList<?> list, int start, int stop,int type){
switch(type){
case RANDOM_PIVOT:
return start+(int)(Math.random()*(stop-start));
case MEDIAN_PIVOT:
Comparable[] i = new Comparable[]{
(Comparable)list.get(0),
(Comparable)list.get(list.size()/2),
(Comparable)list.get(list.size()-1)};
SimpleSort.insertionSort(new SortableComparableArray(i));
if(i[i.length/2].compareTo(list.get(start)) == 0)
return start;
else if(i[i.length/2].compareTo(list.get(stop)) == 0)
return stop;
else
return start+(stop-start)/2;
case MIDDLE_PIVOT:
return (start+stop)/2;
}
return 0;
if(left <= right){
list.swap(left, right);
left++;
right--;
}
}while(left <= right);
if(start < right){
sort(list, start, right, type, insertionSort);
}
if(left < stop){
sort(list, left, stop, type, insertionSort);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static int pivot(SortableDataList<?> list, int start, int stop,int type){
switch(type){
case RANDOM_PIVOT:
return start+(int)(Math.random()*(stop-start));
case MEDIAN_PIVOT:
Comparable[] i = new Comparable[]{
(Comparable)list.get(0),
(Comparable)list.get(list.size()/2),
(Comparable)list.get(list.size()-1)};
SimpleSort.insertionSort(new SortableComparableArray(i));
if(i[i.length/2].compareTo(list.get(start)) == 0)
return start;
else if(i[i.length/2].compareTo(list.get(stop)) == 0)
return stop;
else
return start+(stop-start)/2;
case MIDDLE_PIVOT:
return (start+stop)/2;
}
return 0;
}
}

View file

@ -33,16 +33,16 @@ import zutil.algo.sort.sortable.SortableDataList;
* @author Ziver
*/
public class Randomizer {
/**
* Randomizes the index of all the elements
* @param list The list
*/
@SuppressWarnings({ "rawtypes" })
public static void sort(SortableDataList list){
int size = list.size();
for(int i=0; i<size ;i++){
list.swap(i, (int)(Math.random()*size));
}
}
/**
* Randomizes the index of all the elements
* @param list The list
*/
@SuppressWarnings({ "rawtypes" })
public static void sort(SortableDataList list){
int size = list.size();
for(int i=0; i<size ;i++){
list.swap(i, (int)(Math.random()*size));
}
}
}

View file

@ -28,42 +28,39 @@ import java.util.ArrayList;
@SuppressWarnings({ "unchecked", "rawtypes" })
public class SortableArrayList<T> implements SortableDataList<T>{
private ArrayList<T> list;
public SortableArrayList(ArrayList<T> list){
this.list = list;
}
private ArrayList<T> list;
public T get(int i) {
return list.get(i);
}
public void set(int i, T o){
list.set(i, o);
}
public SortableArrayList(ArrayList<T> list){
this.list = list;
}
public int size() {
return list.size();
}
public T get(int i) {
return list.get(i);
}
public void swap(int a, int b) {
T temp = list.get(a);
list.set(a, list.get(b));
list.set(b, temp);
}
public int compare(int a, int b) {
Comparable aa = (Comparable)list.get(a);
Comparable bb = (Comparable)list.get(b);
return aa.compareTo(bb);
}
public void set(int i, T o){
list.set(i, o);
}
public int compare(int a, T b) {
Comparable aa = (Comparable)list.get(a);
Comparable bb = (Comparable)b;
return aa.compareTo(bb);
}
public int size() {
return list.size();
}
public void swap(int a, int b) {
T temp = list.get(a);
list.set(a, list.get(b));
list.set(b, temp);
}
public int compare(int a, int b) {
Comparable aa = (Comparable)list.get(a);
Comparable bb = (Comparable)list.get(b);
return aa.compareTo(bb);
}
public int compare(int a, T b) {
Comparable aa = (Comparable)list.get(a);
Comparable bb = (Comparable)b;
return aa.compareTo(bb);
}
}

View file

@ -26,50 +26,47 @@ package zutil.algo.sort.sortable;
@SuppressWarnings({ "unchecked", "rawtypes" })
public class SortableComparableArray implements SortableDataList<Comparable>{
private Comparable[] list;
public SortableComparableArray(Comparable[] list){
this.list = list;
}
public Comparable get(int i) {
return list[i];
}
public void set(int i, Comparable o){
list[i] = o;
}
private Comparable[] list;
public int size() {
return list.length;
}
public SortableComparableArray(Comparable[] list){
this.list = list;
}
public void swap(int a, int b) {
Comparable temp = list[a];
list[a] = list[b];
list[b] = temp;
}
public Comparable get(int i) {
return list[i];
}
public int compare(int a, int b) {
if(list[a].compareTo(list[b]) < 0){
return -1;
}
else if(list[a].compareTo(list[b]) > 0){
return 1;
}
return 0;
}
public void set(int i, Comparable o){
list[i] = o;
}
public int compare(int a, Comparable b) {
if(list[a].compareTo(b) < 0){
return -1;
}
else if(list[a].compareTo(b) > 0){
return 1;
}
return 0;
}
public int size() {
return list.length;
}
public void swap(int a, int b) {
Comparable temp = list[a];
list[a] = list[b];
list[b] = temp;
}
public int compare(int a, int b) {
if(list[a].compareTo(list[b]) < 0){
return -1;
}
else if(list[a].compareTo(list[b]) > 0){
return 1;
}
return 0;
}
public int compare(int a, Comparable b) {
if(list[a].compareTo(b) < 0){
return -1;
}
else if(list[a].compareTo(b) > 0){
return 1;
}
return 0;
}
}

View file

@ -25,49 +25,49 @@
package zutil.algo.sort.sortable;
public class SortableIntArray implements SortableDataList<Integer>{
private int[] list;
public SortableIntArray(int[] list){
this.list = list;
}
public Integer get(int i) {
return list[i];
}
private int[] list;
public void set(int i, Integer o){
list[i] = o;
}
public int size() {
return list.length;
}
public SortableIntArray(int[] list){
this.list = list;
}
public void swap(int a, int b) {
int temp = list[a];
list[a] = list[b];
list[b] = temp;
}
public Integer get(int i) {
return list[i];
}
public int compare(int a, int b) {
if(list[a] < list[b]){
return -1;
}
else if(list[a] > list[b]){
return 1;
}
return 0;
}
public void set(int i, Integer o){
list[i] = o;
}
public int compare(int a, Integer b) {
if(list[a] < b){
return -1;
}
else if(list[a] > b){
return 1;
}
return 0;
}
public int size() {
return list.length;
}
public void swap(int a, int b) {
int temp = list[a];
list[a] = list[b];
list[b] = temp;
}
public int compare(int a, int b) {
if(list[a] < list[b]){
return -1;
}
else if(list[a] > list[b]){
return 1;
}
return 0;
}
public int compare(int a, Integer b) {
if(list[a] < b){
return -1;
}
else if(list[a] > b){
return 1;
}
return 0;
}

View file

@ -28,42 +28,42 @@ import java.util.LinkedList;
@SuppressWarnings({ "unchecked", "rawtypes" })
public class SortableLinkedList<T> implements SortableDataList<T>{
private LinkedList<T> list;
public SortableLinkedList(LinkedList<T> list){
this.list = list;
}
private LinkedList<T> list;
public T get(int i) {
return list.get(i);
}
public void set(int i, T o){
list.set(i, o);
}
public SortableLinkedList(LinkedList<T> list){
this.list = list;
}
public int size() {
return list.size();
}
public T get(int i) {
return list.get(i);
}
public void set(int i, T o){
list.set(i, o);
}
public int size() {
return list.size();
}
public void swap(int a, int b) {
T temp = list.get(a);
list.set(a, list.get(b));
list.set(b, temp);
}
public int compare(int a, int b) {
Comparable aa = (Comparable)list.get(a);
Comparable bb = (Comparable)list.get(b);
return aa.compareTo(bb);
}
public int compare(int a, T b) {
Comparable aa = (Comparable)list.get(a);
Comparable bb = (Comparable)b;
return aa.compareTo(bb);
}
public void swap(int a, int b) {
T temp = list.get(a);
list.set(a, list.get(b));
list.set(b, temp);
}
public int compare(int a, int b) {
Comparable aa = (Comparable)list.get(a);
Comparable bb = (Comparable)list.get(b);
return aa.compareTo(bb);
}
public int compare(int a, T b) {
Comparable aa = (Comparable)list.get(a);
Comparable bb = (Comparable)b;
return aa.compareTo(bb);
}
}

View file

@ -33,61 +33,61 @@ import java.util.Iterator;
import java.util.Map;
public class Converter {
private Converter(){}
private Converter(){}
/**
* Converts an object to an array of bytes.
*
* @param object the object to convert.
* @return the associated byte array.
*/
public static byte[] toBytes(Object object) throws IOException{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
/**
* Converts an object to an array of bytes.
*
* @param object the object to convert.
* @return the associated byte array.
*/
public static byte[] toBytes(Object object) throws IOException{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.flush();
oos.close();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.flush();
oos.close();
return baos.toByteArray();
}
/**
* Converts a Integer to an byte array
*
* @param num is the number to convert
* @return a byte array of four bytes
*/
public static byte[] toBytes(int num){
return new byte[]{
(byte)(num & 0xff),
(byte)((num >> 8)& 0xff),
(byte)((num >> 16)& 0xff),
(byte)((num >> 24)& 0xff)};
}
return baos.toByteArray();
}
/**
* Converts a Integer to an byte array
*
* @param num is the number to convert
* @return a byte array of four bytes
*/
public static byte[] toBytes(int num){
return new byte[]{
(byte)(num & 0xff),
(byte)((num >> 8)& 0xff),
(byte)((num >> 16)& 0xff),
(byte)((num >> 24)& 0xff)};
}
/**
* Converts a char array to a byte array.
*
* @return a byte array with the same binary value as the char.
*/
public static byte[] toBytes(char[] arr){
public static byte[] toBytes(char[] arr){
byte[] ret = new byte[arr.length];
for (int i=0; i<arr.length; ++i)
ret[i] = (byte) (arr[i] & 0xFF);
for (int i=0; i<arr.length; ++i)
ret[i] = (byte) (arr[i] & 0xFF);
//System.arraycopy(arr, 0, ret, 0, arr.length); // does not work if char value is largen than 128
return ret;
}
/**
* Converts a Integer to a byte
*
* @param num is the number to convert
* @return a byte value of the integer
*/
public static byte toByte(int num){
return (byte)(num & 0xff);
}
/**
* Converts a Integer to a byte
*
* @param num is the number to convert
* @return a byte value of the integer
*/
public static byte toByte(int num){
return (byte)(num & 0xff);
}
/**
* Converts hex string to a byte array
@ -110,76 +110,76 @@ public class Converter {
return b;
}
/**
* Converts hex chars to a byte
*
* @param quad1 is the first hex value
* @param quad2 is the second hex value
* @return a byte that corresponds to the hex
*/
public static byte hexToByte( char quad1, char quad2){
byte b = hexToByte( quad2 );
b |= hexToByte( quad1 ) << 4;
return b;
}
/**
* Converts a hex chars to a byte
*
* @param hex is the hex value
* @return a byte that corresponds to the hex
* @throws IllegalArgumentException if hex is not a valid hex character
*/
public static byte hexToByte( char hex ) throws IllegalArgumentException{
switch( Character.toLowerCase(hex) ){
case '0': return 0x00;
case '1': return 0x01;
case '2': return 0x02;
case '3': return 0x03;
case '4': return 0x04;
case '5': return 0x05;
case '6': return 0x06;
case '7': return 0x07;
case '8': return 0x08;
case '9': return 0x09;
case 'a': return 0x0a;
case 'b': return 0x0b;
case 'c': return 0x0c;
case 'd': return 0x0d;
case 'e': return 0x0e;
case 'f': return 0x0f;
default:
throw new IllegalArgumentException("'"+hex+"' is an illegal hex character only 0-9 and a-f characters allowed");
}
}
/**
* Converts hex chars to a byte
*
* @param quad1 is the first hex value
* @param quad2 is the second hex value
* @return a byte that corresponds to the hex
*/
public static byte hexToByte( char quad1, char quad2){
byte b = hexToByte( quad2 );
b |= hexToByte( quad1 ) << 4;
return b;
}
/**
* Converts an array of bytes back to its constituent object. The
* input array is assumed to have been created from the original object.
*
* @param bytes the byte array to convert.
* @return the associated object.
*/
public static Object toObject(byte[] bytes) throws Exception{
Object object;
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
object = ois.readObject();
ois.close();
/**
* Converts a hex chars to a byte
*
* @param hex is the hex value
* @return a byte that corresponds to the hex
* @throws IllegalArgumentException if hex is not a valid hex character
*/
public static byte hexToByte( char hex ) throws IllegalArgumentException{
switch( Character.toLowerCase(hex) ){
case '0': return 0x00;
case '1': return 0x01;
case '2': return 0x02;
case '3': return 0x03;
case '4': return 0x04;
case '5': return 0x05;
case '6': return 0x06;
case '7': return 0x07;
case '8': return 0x08;
case '9': return 0x09;
case 'a': return 0x0a;
case 'b': return 0x0b;
case 'c': return 0x0c;
case 'd': return 0x0d;
case 'e': return 0x0e;
case 'f': return 0x0f;
default:
throw new IllegalArgumentException("'"+hex+"' is an illegal hex character only 0-9 and a-f characters allowed");
}
}
return object;
}
/**
* Converts an array of bytes back to its constituent object. The
* input array is assumed to have been created from the original object.
*
* @param bytes the byte array to convert.
* @return the associated object.
*/
public static Object toObject(byte[] bytes) throws Exception{
Object object;
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
object = ois.readObject();
ois.close();
/**
* Reads the first Java Serialized object from a stream.
*
* @param input the stream to read from
* @return an parsed object.
*/
public static Object toObject(InputStream input) throws Exception{
ObjectInputStream ois = new ObjectInputStream(input);
// Don't close the stream as it will close the underlying stream.
return ois.readObject();
}
return object;
}
/**
* Reads the first Java Serialized object from a stream.
*
* @param input the stream to read from
* @return an parsed object.
*/
public static Object toObject(InputStream input) throws Exception{
ObjectInputStream ois = new ObjectInputStream(input);
// Don't close the stream as it will close the underlying stream.
return ois.readObject();
}
/**
@ -188,122 +188,122 @@ public class Converter {
* @param raw the byte array to convert
* @return a bit String
*/
public static String toBitString(byte raw){
StringBuilder str = new StringBuilder(8);
for (int i=0; i<8; ++i) {
str.append(raw & 0x01);
raw >>>= 1;
}
return str.reverse().toString();
}
public static String toBitString(byte raw){
StringBuilder str = new StringBuilder(8);
for (int i=0; i<8; ++i) {
str.append(raw & 0x01);
raw >>>= 1;
}
return str.reverse().toString();
}
/** array needed for byteToHex */
private static char[] HEX_CHARS = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
/**
* Converts a byte Array to a Hex String
*
* @param raw the byte array to convert
* @return a hex String
*/
public static String toHexString(byte[][] raw){
StringBuffer ret = new StringBuffer();
for(byte[] a : raw){
for(byte b : a){
ret.append(HEX_CHARS[(int) (b >>> 0x04)& 0x0F ]);
ret.append(HEX_CHARS[(int) b & 0x0F ]);
}
}
/** array needed for byteToHex */
private static char[] HEX_CHARS = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
/**
* Converts a byte Array to a Hex String
*
* @param raw the byte array to convert
* @return a hex String
*/
public static String toHexString(byte[][] raw){
StringBuffer ret = new StringBuffer();
return ret.toString();
}
for(byte[] a : raw){
for(byte b : a){
ret.append(HEX_CHARS[(int) (b >>> 0x04)& 0x0F ]);
ret.append(HEX_CHARS[(int) b & 0x0F ]);
}
}
public static String toHexStringByColumn(byte[][] raw){
StringBuffer ret = new StringBuffer();
for(int col=0; col<raw[0].length ;col++){
for(int row=0; row<raw.length ;row++){
ret.append(HEX_CHARS[(int) (raw[row][col] >>> 0x04)& 0x0F ]);
ret.append(HEX_CHARS[(int) raw[row][col] & 0x0F ]);
}
}
return ret.toString();
}
return ret.toString();
}
/**
* Converts a byte Array to a Hex String
*
* @param raw the byte array to convert
* @return a hex String
*/
public static String toHexString(byte[] raw){
StringBuffer ret = new StringBuffer();
public static String toHexStringByColumn(byte[][] raw){
StringBuffer ret = new StringBuffer();
for(byte b : raw){
ret.append(HEX_CHARS[(int) (b >>> 0x04)& 0x0F ]);
ret.append(HEX_CHARS[(int) b & 0x0F ]);
}
for(int col=0; col<raw[0].length ;col++){
for(int row=0; row<raw.length ;row++){
ret.append(HEX_CHARS[(int) (raw[row][col] >>> 0x04)& 0x0F ]);
ret.append(HEX_CHARS[(int) raw[row][col] & 0x0F ]);
}
}
return ret.toString();
}
return ret.toString();
}
/**
* Converts a byte to a Hex String
*
* @param raw the byte to convert
* @return a hex String
*/
public static String toHexString(byte raw){
String ret = ""+HEX_CHARS[(int) (raw >>> 0x04)& 0x0F ];
ret += ""+HEX_CHARS[(int) raw & 0x0F ];
/**
* Converts a byte Array to a Hex String
*
* @param raw the byte array to convert
* @return a hex String
*/
public static String toHexString(byte[] raw){
StringBuffer ret = new StringBuffer();
return ret;
}
for(byte b : raw){
ret.append(HEX_CHARS[(int) (b >>> 0x04)& 0x0F ]);
ret.append(HEX_CHARS[(int) b & 0x0F ]);
}
/**
* Converts the given byte to a String with 1's and 0's
*
* @param raw the byte to convert
* @return a String with 1's and 0's
*/
public static String toString(byte raw){
StringBuffer ret = new StringBuffer();
for(int i=128; i>0 ;i=( i<1 ? i=0 : i/2 ) ){
ret.append(( (raw & i) == 0 ? '0' : '1'));
}
return ret.toString();
}
return ret.toString();
}
/**
* Converts the given byte array to a String with 1's and 0's
*
* @param raw the byte array to convert
* @return a String with 1's and 0's
*/
public static String toString(byte[] raw){
StringBuffer ret = new StringBuffer();
for(byte b : raw){
for(int i=128; i>0 ;i=( i<1 ? i=0 : i/2 ) ){
ret.append(( (b & i) == 0 ? '0' : '1'));
}
}
return ret.toString();
}
/**
* Converts a byte to a Hex String
*
* @param raw the byte to convert
* @return a hex String
*/
public static String toHexString(byte raw){
String ret = ""+HEX_CHARS[(int) (raw >>> 0x04)& 0x0F ];
ret += ""+HEX_CHARS[(int) raw & 0x0F ];
return ret;
}
/**
* Converts the given byte to a String with 1's and 0's
*
* @param raw the byte to convert
* @return a String with 1's and 0's
*/
public static String toString(byte raw){
StringBuffer ret = new StringBuffer();
for(int i=128; i>0 ;i=( i<1 ? i=0 : i/2 ) ){
ret.append(( (raw & i) == 0 ? '0' : '1'));
}
return ret.toString();
}
/**
* Converts the given byte array to a String with 1's and 0's
*
* @param raw the byte array to convert
* @return a String with 1's and 0's
*/
public static String toString(byte[] raw){
StringBuffer ret = new StringBuffer();
for(byte b : raw){
for(int i=128; i>0 ;i=( i<1 ? i=0 : i/2 ) ){
ret.append(( (b & i) == 0 ? '0' : '1'));
}
}
return ret.toString();
}
/**
* Generates a comma separated string with key and value pairs
*
* @return a comma separated String
*/
public static String toString(Map map){
StringBuilder tmp = new StringBuilder();
tmp.append("{");
Iterator<Object> it = map.keySet().iterator();
while(it.hasNext()){
Object key = it.next();
public static String toString(Map map){
StringBuilder tmp = new StringBuilder();
tmp.append("{");
Iterator<Object> it = map.keySet().iterator();
while(it.hasNext()){
Object key = it.next();
Object value = map.get(key);
tmp.append(key);
tmp.append(key);
if (value != null) {
if (value instanceof String)
tmp.append(": \"").append(value).append("\"");
@ -313,158 +313,158 @@ public class Converter {
else
tmp.append("null");
if(it.hasNext())
tmp.append(", ");
}
tmp.append('}');
return tmp.toString();
}
if(it.hasNext())
tmp.append(", ");
}
tmp.append('}');
return tmp.toString();
}
/**
* Converts a BitSet to a Integer
*
* @param bits the BitSet to convert
* @return a Integer
*/
public static int toInt(BitSet bits){
int ret = 0;
/**
* Converts a BitSet to a Integer
*
* @param bits the BitSet to convert
* @return a Integer
*/
public static int toInt(BitSet bits){
int ret = 0;
for (int i = bits.nextSetBit(0); i >= 0; i = bits.nextSetBit(i+1)) {
ret += Math.pow(2, i);
}
for (int i = bits.nextSetBit(0); i >= 0; i = bits.nextSetBit(i+1)) {
ret += Math.pow(2, i);
}
return ret;
}
/**
* Converts a boolean array(bit sequence whit most significant bit at index 0) to a Integer
*
* @param bits the boolean array to convert
* @return a Integer
*/
public static int toInt(boolean[] bits){
int ret = 0;
return ret;
}
for (int i = bits.length-1; i >= 0; i--) {
if(bits[i])ret += Math.pow(2, bits.length-i-1);
}
/**
* Converts a boolean array(bit sequence whit most significant bit at index 0) to a Integer
*
* @param bits the boolean array to convert
* @return a Integer
*/
public static int toInt(boolean[] bits){
int ret = 0;
return ret;
}
/**
* Converts a byte to a integer
*
* @param b is the byte to convert
* @return the integer value of the byte
*/
public static int toInt(byte b){
return (int)(b & 0xff);
}
for (int i = bits.length-1; i >= 0; i--) {
if(bits[i])ret += Math.pow(2, bits.length-i-1);
}
/**
* Converts a dynamic sized byte array to a integer
*
* @param b is the byte array of size 1-4
* @return the int value of the byte array
*/
public static int toInt(byte[] b){
int i = 0;
switch (b.length){
default:
case 4: i |= 0xFF000000 & (b[3] << 24);
case 3: i |= 0x00FF0000 & (b[2] << 16);
case 2: i |= 0x0000FF00 & (b[1] << 8);
case 1: i |= 0x000000FF & b[0];
case 0: break;
}
return i;
}
return ret;
}
/**
* Converts a Integer to a BitSet
*
* @param num the Integer to convert
* @return a BitSet object
*/
public static BitSet toBitSet(int num){
BitSet ret = new BitSet();
String tmp = Integer.toBinaryString(num);
/**
* Converts a byte to a integer
*
* @param b is the byte to convert
* @return the integer value of the byte
*/
public static int toInt(byte b){
return (int)(b & 0xff);
}
for(int i=0; i<tmp.length() ;i++){
ret.set(i , tmp.charAt(tmp.length()-i-1) != '0');
}
return ret;
}
/**
* Converts a dynamic sized byte array to a integer
*
* @param b is the byte array of size 1-4
* @return the int value of the byte array
*/
public static int toInt(byte[] b){
int i = 0;
switch (b.length){
default:
case 4: i |= 0xFF000000 & (b[3] << 24);
case 3: i |= 0x00FF0000 & (b[2] << 16);
case 2: i |= 0x0000FF00 & (b[1] << 8);
case 1: i |= 0x000000FF & b[0];
case 0: break;
}
return i;
}
/**
* Converts a given String to a specified class
*
* @param <T> is the resulting class
* @param data is the String data to be converted
* @param c is the class to convert to
* @return a instance of the class with the value in the string or null if there was an problem
*/
@SuppressWarnings("unchecked")
public static <T> T fromString(String data, Class<T> c){
if(data == null || data.isEmpty())
return null;
try{
if( c == String.class) return (T) data;
else if(c == Integer.class) return (T) new Integer(data);
else if(c == int.class) return (T) new Integer(data);
else if(c == Long.class) return (T) new Long(data);
else if(c == long.class) return (T) new Long(data);
else if(c == Float.class) return (T) new Float(data);
else if(c == float.class) return (T) new Float(data);
else if(c == Double.class) return (T) new Double(data);
else if(c == double.class) return (T) new Double(data);
else if(c == Boolean.class) return (T) new Boolean(data);
else if(c == boolean.class) return (T) new Boolean(data);
else if(c == Byte.class) return (T) new Byte(data);
else if(c == byte.class) return (T) new Byte(data);
else if(byte[].class.isAssignableFrom(c))
return (T) Base64Decoder.decode(data);
}catch(Exception e){
e.printStackTrace();
}
return null;
}
/**
* Replaces reserved and unsafe characters in URLs with hex values
*/
public static String urlEncode( String str ){
StringBuilder out = new StringBuilder();
for( char c : str.toCharArray() ){
if( c>='0' && c<='9' || c>='A' && c<='Z' || c>='a' && c<='z' ||
c=='$' || c=='-' || c=='_' || c=='.' || c=='+' || c=='!' ||
c=='*' || c=='\'' || c=='(' || c==')' || c==',' )
out.append( c );
else{
out.append( '%' ).append( toHexString((byte)c) );
}
}
return out.toString();
}
/**
* Replaces hex values from a URL with the proper characters
*/
public static String urlDecode( String str ){
StringBuilder out = new StringBuilder();
char[] array = str.toCharArray();
for( int i=0; i<array.length ;i++ ){
char c = array[i];
if( c == '%' && i+2<array.length ){
out.append( (char)hexToByte( array[++i], array[++i]) );
}
else
out.append( c );
}
return out.toString();
}
/**
* Converts a Integer to a BitSet
*
* @param num the Integer to convert
* @return a BitSet object
*/
public static BitSet toBitSet(int num){
BitSet ret = new BitSet();
String tmp = Integer.toBinaryString(num);
for(int i=0; i<tmp.length() ;i++){
ret.set(i , tmp.charAt(tmp.length()-i-1) != '0');
}
return ret;
}
/**
* Converts a given String to a specified class
*
* @param <T> is the resulting class
* @param data is the String data to be converted
* @param c is the class to convert to
* @return a instance of the class with the value in the string or null if there was an problem
*/
@SuppressWarnings("unchecked")
public static <T> T fromString(String data, Class<T> c){
if(data == null || data.isEmpty())
return null;
try{
if( c == String.class) return (T) data;
else if(c == Integer.class) return (T) new Integer(data);
else if(c == int.class) return (T) new Integer(data);
else if(c == Long.class) return (T) new Long(data);
else if(c == long.class) return (T) new Long(data);
else if(c == Float.class) return (T) new Float(data);
else if(c == float.class) return (T) new Float(data);
else if(c == Double.class) return (T) new Double(data);
else if(c == double.class) return (T) new Double(data);
else if(c == Boolean.class) return (T) new Boolean(data);
else if(c == boolean.class) return (T) new Boolean(data);
else if(c == Byte.class) return (T) new Byte(data);
else if(c == byte.class) return (T) new Byte(data);
else if(byte[].class.isAssignableFrom(c))
return (T) Base64Decoder.decode(data);
}catch(Exception e){
e.printStackTrace();
}
return null;
}
/**
* Replaces reserved and unsafe characters in URLs with hex values
*/
public static String urlEncode( String str ){
StringBuilder out = new StringBuilder();
for( char c : str.toCharArray() ){
if( c>='0' && c<='9' || c>='A' && c<='Z' || c>='a' && c<='z' ||
c=='$' || c=='-' || c=='_' || c=='.' || c=='+' || c=='!' ||
c=='*' || c=='\'' || c=='(' || c==')' || c==',' )
out.append( c );
else{
out.append( '%' ).append( toHexString((byte)c) );
}
}
return out.toString();
}
/**
* Replaces hex values from a URL with the proper characters
*/
public static String urlDecode( String str ){
StringBuilder out = new StringBuilder();
char[] array = str.toCharArray();
for( int i=0; i<array.length ;i++ ){
char c = array[i];
if( c == '%' && i+2<array.length ){
out.append( (char)hexToByte( array[++i], array[++i]) );
}
else
out.append( c );
}
return out.toString();
}
}

View file

@ -27,90 +27,90 @@ package zutil.converter;
import java.util.HashMap;
public class NumberToWordsConverter {
private static final String ZERO_STRINGS = "zero";
// Indexes to lookup
private static final int[] NUMERIC_INDEXES = new int[]{
9,/*1000 000 000*/
6,/*1000 000*/
3,/*1000*/
2 /*100*/};
private static final HashMap<Long, String> NUMERIC_STRINGS;
static{
NUMERIC_STRINGS = new HashMap<>();
NUMERIC_STRINGS.put(1l, "one");
NUMERIC_STRINGS.put(2l, "two");
NUMERIC_STRINGS.put(3l, "three");
NUMERIC_STRINGS.put(4l, "four");
NUMERIC_STRINGS.put(5l, "five");
NUMERIC_STRINGS.put(6l, "six");
NUMERIC_STRINGS.put(7l, "seven");
NUMERIC_STRINGS.put(8l, "eight");
NUMERIC_STRINGS.put(9l, "nine");
NUMERIC_STRINGS.put(10l, "ten");
NUMERIC_STRINGS.put(11l, "eleven");
NUMERIC_STRINGS.put(12l, "twelve");
NUMERIC_STRINGS.put(13l, "thirteen");
NUMERIC_STRINGS.put(14l, "fourteen");
NUMERIC_STRINGS.put(15l, "fifteen");
NUMERIC_STRINGS.put(16l, "sixteen");
NUMERIC_STRINGS.put(17l, "seventeen");
NUMERIC_STRINGS.put(18l, "eightteen");
NUMERIC_STRINGS.put(19l, "nineteen");
NUMERIC_STRINGS.put(20l, "twenty");
NUMERIC_STRINGS.put(30l, "thirty");
NUMERIC_STRINGS.put(40l, "forty");
NUMERIC_STRINGS.put(50l, "fifty");
NUMERIC_STRINGS.put(60l, "sixty");
NUMERIC_STRINGS.put(70l, "seventy");
NUMERIC_STRINGS.put(80l, "eighty");
NUMERIC_STRINGS.put(90l, "ninety");
NUMERIC_STRINGS.put(100l, "hundred");
NUMERIC_STRINGS.put(1_000l, "thousand");
NUMERIC_STRINGS.put(1000_000l, "million");
NUMERIC_STRINGS.put(1000_000_000l, "billion");
}
/**
* Given an integer in the range -20 to 20 will return a String with
* that number converted to words. For example, an input of 15 results in
* an output of "fifteen". An input of -4 returns "minus four".
*
* @param num a number to be converted to words.
* @return the number as words.
*/
public String convert(int num) {
if (num == 0)
return ZERO_STRINGS;
long tmpNum = num;
StringBuilder buffer = new StringBuilder();
if (tmpNum < 0){ // Negative number
tmpNum *= -1;
buffer.append("minus ");
}
for(int i : NUMERIC_INDEXES){
long pow = (int)Math.pow(10, i);
if (tmpNum >= pow){
long numberAtIndex = tmpNum/pow; // The number at position 3
tmpNum -= numberAtIndex*pow;
buffer.append( convert((int)numberAtIndex) ).append(" ");
buffer.append( NUMERIC_STRINGS.get( pow ) ).append(" ");
}
}
if (tmpNum >= 20){ // second number in the integer
long numberAtIndex = ((tmpNum % 100)/10)*10; // The number at position 2
tmpNum -= numberAtIndex;
buffer.append( NUMERIC_STRINGS.get(numberAtIndex) ).append(" ");
}
if (NUMERIC_STRINGS.containsKey(tmpNum))
buffer.append(NUMERIC_STRINGS.get(tmpNum));
return buffer.toString().trim();
}
private static final String ZERO_STRINGS = "zero";
// Indexes to lookup
private static final int[] NUMERIC_INDEXES = new int[]{
9,/*1000 000 000*/
6,/*1000 000*/
3,/*1000*/
2 /*100*/};
private static final HashMap<Long, String> NUMERIC_STRINGS;
static{
NUMERIC_STRINGS = new HashMap<>();
NUMERIC_STRINGS.put(1l, "one");
NUMERIC_STRINGS.put(2l, "two");
NUMERIC_STRINGS.put(3l, "three");
NUMERIC_STRINGS.put(4l, "four");
NUMERIC_STRINGS.put(5l, "five");
NUMERIC_STRINGS.put(6l, "six");
NUMERIC_STRINGS.put(7l, "seven");
NUMERIC_STRINGS.put(8l, "eight");
NUMERIC_STRINGS.put(9l, "nine");
NUMERIC_STRINGS.put(10l, "ten");
NUMERIC_STRINGS.put(11l, "eleven");
NUMERIC_STRINGS.put(12l, "twelve");
NUMERIC_STRINGS.put(13l, "thirteen");
NUMERIC_STRINGS.put(14l, "fourteen");
NUMERIC_STRINGS.put(15l, "fifteen");
NUMERIC_STRINGS.put(16l, "sixteen");
NUMERIC_STRINGS.put(17l, "seventeen");
NUMERIC_STRINGS.put(18l, "eightteen");
NUMERIC_STRINGS.put(19l, "nineteen");
NUMERIC_STRINGS.put(20l, "twenty");
NUMERIC_STRINGS.put(30l, "thirty");
NUMERIC_STRINGS.put(40l, "forty");
NUMERIC_STRINGS.put(50l, "fifty");
NUMERIC_STRINGS.put(60l, "sixty");
NUMERIC_STRINGS.put(70l, "seventy");
NUMERIC_STRINGS.put(80l, "eighty");
NUMERIC_STRINGS.put(90l, "ninety");
NUMERIC_STRINGS.put(100l, "hundred");
NUMERIC_STRINGS.put(1_000l, "thousand");
NUMERIC_STRINGS.put(1000_000l, "million");
NUMERIC_STRINGS.put(1000_000_000l, "billion");
}
/**
* Given an integer in the range -20 to 20 will return a String with
* that number converted to words. For example, an input of 15 results in
* an output of "fifteen". An input of -4 returns "minus four".
*
* @param num a number to be converted to words.
* @return the number as words.
*/
public String convert(int num) {
if (num == 0)
return ZERO_STRINGS;
long tmpNum = num;
StringBuilder buffer = new StringBuilder();
if (tmpNum < 0){ // Negative number
tmpNum *= -1;
buffer.append("minus ");
}
for(int i : NUMERIC_INDEXES){
long pow = (int)Math.pow(10, i);
if (tmpNum >= pow){
long numberAtIndex = tmpNum/pow; // The number at position 3
tmpNum -= numberAtIndex*pow;
buffer.append( convert((int)numberAtIndex) ).append(" ");
buffer.append( NUMERIC_STRINGS.get( pow ) ).append(" ");
}
}
if (tmpNum >= 20){ // second number in the integer
long numberAtIndex = ((tmpNum % 100)/10)*10; // The number at position 2
tmpNum -= numberAtIndex;
buffer.append( NUMERIC_STRINGS.get(numberAtIndex) ).append(" ");
}
if (NUMERIC_STRINGS.containsKey(tmpNum))
buffer.append(NUMERIC_STRINGS.get(tmpNum));
return buffer.toString().trim();
}
}

View file

@ -25,48 +25,48 @@
package zutil.converter;
public class WGS84Converter {
public static void main(String[] args){
System.out.println(toWGS84Decimal("N 59<35> 47' 43\"")+" "+toWGS84Decimal(" E 17<31> 42' 55\""));
System.out.println(toWGS84Decimal("55<EFBFBD> 0' 0\"")+" "+toWGS84Decimal("68<EFBFBD> 59' 59,999\""));
System.out.println(toWGS84Decimal("55<EFBFBD> 0.001'")+" "+toWGS84Decimal("68<EFBFBD> 59.999'"));
System.out.println(toWGS84Decimal("3444.0000S")+" "+toWGS84Decimal("13521.0000E"));
System.out.println(toWGS84Decimal("-44.0001")+" "+toWGS84Decimal("521.0001"));
}
public static void main(String[] args){
System.out.println(toWGS84Decimal("N 59<35> 47' 43\"")+" "+toWGS84Decimal(" E 17<31> 42' 55\""));
System.out.println(toWGS84Decimal("55<EFBFBD> 0' 0\"")+" "+toWGS84Decimal("68<EFBFBD> 59' 59,999\""));
System.out.println(toWGS84Decimal("55<EFBFBD> 0.001'")+" "+toWGS84Decimal("68<EFBFBD> 59.999'"));
System.out.println(toWGS84Decimal("3444.0000S")+" "+toWGS84Decimal("13521.0000E"));
System.out.println(toWGS84Decimal("-44.0001")+" "+toWGS84Decimal("521.0001"));
}
/**
* Converts an WGS84 coordinate to an WGS84 decimal coordinate
*
* @param coordinate is the coordinate to convert
* @return the new coordinate in decimal degrees, returns 0 if conversions fails
*/
public static float toWGS84Decimal(String coordinate){
float deg=0, min=0, sec=0, neg=1;
coordinate = coordinate.trim().replaceAll(",", ".").toUpperCase();
if(coordinate.contains("S") || coordinate.contains("W"))
neg = -1;
// 55<EFBFBD> 0' 68<EFBFBD> 59,999 or 55<EFBFBD> 0' 0" 68<36> 59' 59,999"
if(coordinate.matches("[NSWE ]? ?[0-9]{1,3}<7D> [0-9]{1,2}.?[0-9]*'[ 0-9.\\\"]*")){
coordinate = coordinate.replaceAll("[NSEW<45>'\\\"]", "").trim();
String[] tmp = coordinate.split(" ");
deg = Float.parseFloat(tmp[0]);
min = Float.parseFloat(tmp[1]);
if(tmp.length > 2){
sec = Float.parseFloat(tmp[2]);
}
}
// 3444.0000S 13521.0000E
else if(coordinate.matches("[0-9]{4,5}.[0-9]*[NSEW]{1}")){
coordinate = coordinate.replaceAll("[NS EW]", "");
float tmpf = Float.parseFloat(coordinate);
deg = (int)(tmpf/100);
min = tmpf-(deg*100);
}
// 55.0 68.99999
else if(coordinate.matches("\\-?[0-9]{2,3}.[0-9]*")){
return Float.parseFloat(coordinate);
}
return neg*(deg + min/60 + sec/3600);
}
/**
* Converts an WGS84 coordinate to an WGS84 decimal coordinate
*
* @param coordinate is the coordinate to convert
* @return the new coordinate in decimal degrees, returns 0 if conversions fails
*/
public static float toWGS84Decimal(String coordinate){
float deg=0, min=0, sec=0, neg=1;
coordinate = coordinate.trim().replaceAll(",", ".").toUpperCase();
if(coordinate.contains("S") || coordinate.contains("W"))
neg = -1;
// 55<EFBFBD> 0' 68<EFBFBD> 59,999 or 55<EFBFBD> 0' 0" 68<36> 59' 59,999"
if(coordinate.matches("[NSWE ]? ?[0-9]{1,3}<7D> [0-9]{1,2}.?[0-9]*'[ 0-9.\\\"]*")){
coordinate = coordinate.replaceAll("[NSEW<45>'\\\"]", "").trim();
String[] tmp = coordinate.split(" ");
deg = Float.parseFloat(tmp[0]);
min = Float.parseFloat(tmp[1]);
if(tmp.length > 2){
sec = Float.parseFloat(tmp[2]);
}
}
// 3444.0000S 13521.0000E
else if(coordinate.matches("[0-9]{4,5}.[0-9]*[NSEW]{1}")){
coordinate = coordinate.replaceAll("[NS EW]", "");
float tmpf = Float.parseFloat(coordinate);
deg = (int)(tmpf/100);
min = tmpf-(deg*100);
}
// 55.0 68.99999
else if(coordinate.matches("\\-?[0-9]{2,3}.[0-9]*")){
return Float.parseFloat(coordinate);
}
return neg*(deg + min/60 + sec/3600);
}
}

View file

@ -37,162 +37,162 @@ import java.util.TimerTask;
* @author Ziver
*/
public class DBConnectionPool extends TimerTask implements Closeable{
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;
public static final long DEFAULT_TIMEOUT = 10*60*60*1000; // 10 minutes;
public static final int DEFAULT_MAX_SIZE = 5;
// Pool details
private int max_conn;
private long timeout;
private Timer timeout_timer;
// DB details
private DBMS dbms;
private String url;
private String db;
private String user;
private String password;
protected class PoolItem{
public DBConnection conn;
public long timestamp;
// Pool details
private int max_conn;
private long timeout;
private Timer timeout_timer;
public boolean equals(Object o){
return conn.equals(o);
}
}
protected class PoolItem{
public DBConnection conn;
public long timestamp;
// The pool
private LinkedList<PoolItem> inusePool;
private LinkedList<PoolItem> readyPool;
public boolean equals(Object o){
return conn.equals(o);
}
}
/**
* 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;
// The pool
private LinkedList<PoolItem> inusePool;
private LinkedList<PoolItem> readyPool;
inusePool = new LinkedList<PoolItem>();
readyPool = new LinkedList<PoolItem>();
this.setTimeout(DEFAULT_TIMEOUT);
this.setMaxSize(DEFAULT_MAX_SIZE);
}
/**
* 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;
/**
* 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);
}
inusePool = new LinkedList<PoolItem>();
readyPool = new LinkedList<PoolItem>();
/**
* Removes an connection from the pool
*
* @param conn is the connection to remove
*/
protected void removeConnection(DBConnection conn){
inusePool.remove(conn);
readyPool.remove(conn);
}
this.setTimeout(DEFAULT_TIMEOUT);
this.setMaxSize(DEFAULT_MAX_SIZE);
}
/**
* 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 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);
}
/**
* 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);
}
/**
* Removes an connection from the pool
*
* @param conn is the connection to remove
*/
protected void removeConnection(DBConnection conn){
inusePool.remove(conn);
readyPool.remove(conn);
}
/**
* @return the current size of the pool
*/
public int size(){
return inusePool.size() + readyPool.size();
}
/**
* 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;
}
}
/**
* Closes all the connections
*/
public synchronized void close(){
for( PoolItem item : inusePool ){
item.conn.forceClose();
}
inusePool.clear();
for( PoolItem item : readyPool ){
item.conn.forceClose();
}
readyPool.clear();
}
/**
* 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);
}
/**
* Set the max size of the pool
*/
public void setMaxSize(int max){
this.max_conn = max;
}
/**
* @return the current size of the pool
*/
public int size(){
return inusePool.size() + readyPool.size();
}
/**
* 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);
}
/**
* Closes all the connections
*/
public synchronized void close(){
for( PoolItem item : inusePool ){
item.conn.forceClose();
}
inusePool.clear();
for( PoolItem item : readyPool ){
item.conn.forceClose();
}
readyPool.clear();
}
/**
* Checks every DB connection if they are valid and has not timed out
*/
public void run(){
long stale = System.currentTimeMillis() - timeout;
/**
* Set the max size of the pool
*/
public void setMaxSize(int max){
this.max_conn = max;
}
for(PoolItem item : inusePool){
if( !item.conn.valid() && stale > item.timestamp ) {
removeConnection(item.conn);
item.conn.forceClose();
}
}
}
/**
* 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();
}
}
}
}

View file

@ -49,168 +49,168 @@ import java.util.Queue;
*
*/
public class DBQueue<E> implements Queue<E>{
private DBConnection db;
private String table;
/**
* Initiates the queue.<br>
*
* @param db is the connection to the DB
* @param table is the name of the table
*/
public DBQueue(DBConnection db, String table){
this.db = db;
this.table = table;
}
private DBConnection db;
private String table;
public boolean add(Object arg0){
try {
PreparedStatement sql = db.getPreparedStatement("INSERT INTO ? (data) VALUES(?)");
/**
* Initiates the queue.<br>
*
* @param db is the connection to the DB
* @param table is the name of the table
*/
public DBQueue(DBConnection db, String table){
this.db = db;
this.table = table;
}
public boolean add(Object arg0){
try {
PreparedStatement sql = db.getPreparedStatement("INSERT INTO ? (data) VALUES(?)");
sql.setObject(1, table);
sql.setObject(2, arg0);
DBConnection.exec(sql);
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
return false;
}
return true;
}
public E element() {
return peek();
}
sql.setObject(2, arg0);
DBConnection.exec(sql);
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
return false;
}
return true;
}
public boolean offer(Object arg0) {
return add(arg0);
}
public E element() {
return peek();
}
public synchronized E peek() {
try {
return db.exec("SELECT * FROM "+table+" LIMIT 1", new SQLResultHandler<E>(){
public E handleQueryResult(Statement stmt, ResultSet rs) throws SQLException{
if (rs.next())
try {
return (E) Converter.toObject(rs.getBytes("data"));
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return null;
}
});
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return null;
}
public boolean offer(Object arg0) {
return add(arg0);
}
public synchronized E poll() {
try {
return db.exec("SELECT * FROM "+table+" LIMIT 1", new SQLResultHandler<E>(){
public E handleQueryResult(Statement stmt, ResultSet rs) {
try{
if (rs.next()) {
db.exec("DELETE FROM "+table+" WHERE id="+rs.getInt("id")+" LIMIT 1");
return (E) Converter.toObject(rs.getBytes("data"));
}
}catch(Exception e){
e.printStackTrace(MultiPrintStream.out);
}
return null;
}
});
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return null;
}
public synchronized E peek() {
try {
return db.exec("SELECT * FROM "+table+" LIMIT 1", new SQLResultHandler<E>(){
public E handleQueryResult(Statement stmt, ResultSet rs) throws SQLException{
if (rs.next())
try {
return (E) Converter.toObject(rs.getBytes("data"));
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return null;
}
});
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return null;
}
public E remove() {
return poll();
}
public synchronized E poll() {
try {
return db.exec("SELECT * FROM "+table+" LIMIT 1", new SQLResultHandler<E>(){
public E handleQueryResult(Statement stmt, ResultSet rs) {
try{
if (rs.next()) {
db.exec("DELETE FROM "+table+" WHERE id="+rs.getInt("id")+" LIMIT 1");
return (E) Converter.toObject(rs.getBytes("data"));
}
}catch(Exception e){
e.printStackTrace(MultiPrintStream.out);
}
return null;
}
});
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return null;
}
public boolean addAll(Collection<? extends E> arg0) {
// TODO Auto-generated method stub
return false;
}
public E remove() {
return poll();
}
public void clear() {
try {
db.exec("TRUNCATE TABLE `"+table+"`");
} catch (SQLException e) {
e.printStackTrace(MultiPrintStream.out);
}
}
public boolean addAll(Collection<? extends E> arg0) {
// TODO Auto-generated method stub
return false;
}
public boolean contains(Object arg0) {
try {
return db.exec("SELECT data FROM "+table+" WHERE data='"+Converter.toBytes(arg0)+"' LIMIT 1", new SQLResultHandler<Boolean>(){
public Boolean handleQueryResult(Statement stmt, ResultSet rs) throws SQLException{
return rs.next();
}
});
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return false;
}
public void clear() {
try {
db.exec("TRUNCATE TABLE `"+table+"`");
} catch (SQLException e) {
e.printStackTrace(MultiPrintStream.out);
}
}
public boolean containsAll(Collection<?> arg0) {
// TODO Auto-generated method stub
return false;
}
public boolean contains(Object arg0) {
try {
return db.exec("SELECT data FROM "+table+" WHERE data='"+Converter.toBytes(arg0)+"' LIMIT 1", new SQLResultHandler<Boolean>(){
public Boolean handleQueryResult(Statement stmt, ResultSet rs) throws SQLException{
return rs.next();
}
});
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return false;
}
public boolean isEmpty() {
return (peek() != null);
}
public boolean containsAll(Collection<?> arg0) {
// TODO Auto-generated method stub
return false;
}
public Iterator<E> iterator() {
// TODO: Auto-generated method stub
return null;
}
public boolean isEmpty() {
return (peek() != null);
}
public synchronized boolean remove(Object arg0) {
try {
db.exec("DELETE FROM "+table+" WHERE data='"+Converter.toBytes(arg0)+"' LIMIT 1");
return true;
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return false;
}
public Iterator<E> iterator() {
// TODO: Auto-generated method stub
return null;
}
public synchronized boolean removeAll(Collection<?> arg0) {
// TODO Auto-generated method stub
return false;
}
public synchronized boolean remove(Object arg0) {
try {
db.exec("DELETE FROM "+table+" WHERE data='"+Converter.toBytes(arg0)+"' LIMIT 1");
return true;
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return false;
}
public boolean retainAll(Collection<?> arg0) {
// TODO Auto-generated method stub
return false;
}
public synchronized boolean removeAll(Collection<?> arg0) {
// TODO Auto-generated method stub
return false;
}
public int size() {
try {
return db.exec("SELECT count(*) FROM "+table, new SQLResultHandler<Integer>(){
public Integer handleQueryResult(Statement stmt, ResultSet rs) throws SQLException{
if (rs.next())
return rs.getInt(1);
return 0;
}
});
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return 0;
}
public boolean retainAll(Collection<?> arg0) {
// TODO Auto-generated method stub
return false;
}
public E[] toArray() {
// TODO Auto-generated method stub
return null;
}
public int size() {
try {
return db.exec("SELECT count(*) FROM "+table, new SQLResultHandler<Integer>(){
public Integer handleQueryResult(Statement stmt, ResultSet rs) throws SQLException{
if (rs.next())
return rs.getInt(1);
return 0;
}
});
} catch (Exception e) {
e.printStackTrace(MultiPrintStream.out);
}
return 0;
}
public E[] toArray(Object[] arg0) {
// TODO Auto-generated method stub
return null;
}
public E[] toArray() {
// TODO Auto-generated method stub
return null;
}
public E[] toArray(Object[] arg0) {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -32,393 +32,393 @@ import java.util.LinkedList;
* @author Ziver
*/
public class SQLQuery {
protected static abstract class SQLQueryItem{
SQLQueryItem root;
protected SQLQueryItem(){}
protected void setRoot(SQLQueryItem root){
this.root = root;
}
protected abstract void build(StringBuilder query);
public String toString(){
StringBuilder query = new StringBuilder();
root.build(query);
return query.toString();
}
}
protected static abstract class SQLQueryItem{
SQLQueryItem root;
//*******************************************
// Main Types
/**
* <XMP>
* SELECT
* [ALL | DISTINCT | DISTINCTROW ]
* [FROM table_references
* [WHERE where_condition]
* [GROUP BY {col_name | expr | position}
* [ASC | DESC], ... [WITH ROLLUP]]
* [HAVING where_condition]
* [ORDER BY {col_name | expr | position}
* [ASC | DESC], ...]
* [LIMIT {[offset,] row_count | row_count OFFSET offset}]
* </XMP>
*/
public static class SQLSelect extends SQLQueryItem{
String[] params;
SQLFrom from;
protected SQLQueryItem(){}
/**
* @param params is the columns that you want out of the SELECT query, leave empty for all columns
*/
protected SQLSelect(String ...params ){
setRoot(this);
this.params = params;
}
protected void build(StringBuilder query) {
query.append("SELECT ");
if( params == null || params.length <= 0 )
query.append("*");
else{
for(int i=0; i<params.length ;i++){
query.append(params[i]);
if( i != params.length-1 )
query.append(",");
}
}
if( from != null )
from.build( query );
}
public SQLFrom FROM(String ...tables){
return from = new SQLFrom(this, tables);
}
}
/*
* <XMP>
* UPDATE [LOW_PRIORITY] [IGNORE] table_reference
* SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
* [WHERE where_condition]
* [ORDER BY ...]
* [LIMIT row_count]
* </XMP>
*/
public static class SQLUpdate extends SQLQueryItem{
protected SQLUpdate(){
setRoot(this);
}
protected void build(StringBuilder query) {
}
}
/*
* <XMP>
* INSERT [INTO] tbl_name
* SET col_name={expr | DEFAULT}, ...
*
* INSERT [INTO] tbl_name [(col_name,...)]
* {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
* </XMP>
*/
public static class SQLInsert extends SQLQueryItem{
protected SQLInsert(){
setRoot(this);
}
protected void build(StringBuilder query) {
}
}
/*
* <XMP>
* DELETE FROM tbl_name
* [WHERE where_condition]
* [ORDER BY ...]
* [LIMIT row_count]
* </XMP>
*/
public static class SQLDelete extends SQLQueryItem{
protected SQLDelete(){
setRoot(this);
}
protected void build(StringBuilder query) {
}
}
//*******************************************
// Sub Types
public static class SQLFrom extends SQLQueryItem{
LinkedList<String> tables = new LinkedList<String>();
SQLQueryItem next;
protected void setRoot(SQLQueryItem root){
this.root = root;
}
protected abstract void build(StringBuilder query);
public String toString(){
StringBuilder query = new StringBuilder();
root.build(query);
return query.toString();
}
}
//*******************************************
// Main Types
/**
* <XMP>
* SELECT
* [ALL | DISTINCT | DISTINCTROW ]
* [FROM table_references
* [WHERE where_condition]
* [GROUP BY {col_name | expr | position}
* [ASC | DESC], ... [WITH ROLLUP]]
* [HAVING where_condition]
* [ORDER BY {col_name | expr | position}
* [ASC | DESC], ...]
* [LIMIT {[offset,] row_count | row_count OFFSET offset}]
* </XMP>
*/
public static class SQLSelect extends SQLQueryItem{
String[] params;
SQLFrom from;
/**
* @param params is the columns that you want out of the SELECT query, leave empty for all columns
*/
protected SQLSelect(String ...params ){
setRoot(this);
this.params = params;
}
protected void build(StringBuilder query) {
query.append("SELECT ");
if( params == null || params.length <= 0 )
query.append("*");
else{
for(int i=0; i<params.length ;i++){
query.append(params[i]);
if( i != params.length-1 )
query.append(",");
}
}
if( from != null )
from.build( query );
}
public SQLFrom FROM(String ...tables){
return from = new SQLFrom(this, tables);
}
}
/*
* <XMP>
* UPDATE [LOW_PRIORITY] [IGNORE] table_reference
* SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
* [WHERE where_condition]
* [ORDER BY ...]
* [LIMIT row_count]
* </XMP>
*/
public static class SQLUpdate extends SQLQueryItem{
protected SQLUpdate(){
setRoot(this);
}
protected void build(StringBuilder query) {
}
}
/*
* <XMP>
* INSERT [INTO] tbl_name
* SET col_name={expr | DEFAULT}, ...
*
* INSERT [INTO] tbl_name [(col_name,...)]
* {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
* </XMP>
*/
public static class SQLInsert extends SQLQueryItem{
protected SQLInsert(){
setRoot(this);
}
protected void build(StringBuilder query) {
}
}
/*
* <XMP>
* DELETE FROM tbl_name
* [WHERE where_condition]
* [ORDER BY ...]
* [LIMIT row_count]
* </XMP>
*/
public static class SQLDelete extends SQLQueryItem{
protected SQLDelete(){
setRoot(this);
}
protected void build(StringBuilder query) {
}
}
//*******************************************
// Sub Types
public static class SQLFrom extends SQLQueryItem{
LinkedList<String> tables = new LinkedList<String>();
SQLQueryItem next;
protected SQLFrom(SQLQueryItem root, String ...tables){
setRoot(root);
for( String table : tables )
this.tables.add(table);
}
public SQLFrom NATURAL_JOIN(String table){
return joinLastTable("NATURAL JOIN", table);
}
public SQLFrom NATURAL_JOIN(String ...tables){
return joinTable("NATURAL JOIN", tables);
}
public SQLFrom JOIN(String table){
return joinLastTable("JOIN", table);
}
public SQLFrom JOIN(String ...tables){
return joinTable("JOIN", tables);
}
public SQLFrom UNION(String table){
return joinLastTable("UNION", table);
}
public SQLFrom UNION(String ...tables){
return joinTable("UNION", tables);
}
private SQLFrom joinLastTable(String type, String table){
String last = tables.getLast();
tables.removeLast();
tables.add(
new StringBuilder(last).append(" ").append(type).append(" ").append(table).toString());
return this;
}
private SQLFrom joinTable(String type, String[] tables){
if( tables.length < 2 )
return this;
StringBuilder str = new StringBuilder();
for(int i=0; i<tables.length ;i++){
str.append(tables[i]);
if( i != tables.length-1 )
str.append(' ').append(type).append(' ');
}
this.tables.add(str.toString());
return this;
}
public SQLWhere WHERE(){
return (SQLWhere) (next = new SQLWhere(root));
}
public SQLGroupBy GROUP_BY( String ...cols ){
return (SQLGroupBy) (next = new SQLGroupBy(root, cols));
}
public SQLOrderBy ORDER_BY( String ...cols ){
return (SQLOrderBy) (next = new SQLOrderBy(root, cols));
}
public SQLLimit LIMIT( long count ){
return (SQLLimit) (next = new SQLLimit(root, count));
}
protected void build(StringBuilder query) {
query.append(" FROM ");
if( tables.isEmpty() )
throw new RuntimeException("The FROM query item must have at least 1 table!");
for(int i=0; i<tables.size() ;i++){
query.append(tables.get(i));
if( i != tables.size()-1 )
query.append(", ");
}
if( next != null ) next.build( query );
}
}
//*******************************************
// Condition Types
public static class SQLWhere extends SQLQueryItem{
LinkedList<String> conds = new LinkedList<String>();
SQLQueryItem next;
protected SQLWhere(SQLQueryItem root){
setRoot(root);
}
/**
* Equals (arg1 = arg2)
*/
public SQLWhere EQ(String arg1, String arg2){
return cond("=", arg1, arg2);
}
/**
* Not Equal (arg1 != arg2)
*/
public SQLWhere NE(String arg1, String arg2){
return cond("!=", arg1, arg2);
}
/**
* Less than (arg1 < arg2)
*/
public SQLWhere LT(String arg1, String arg2){
return cond("<", arg1, arg2);
}
/**
* Greater than (arg1 > arg2)
*/
public SQLWhere GT(String arg1, String arg2){
return cond(">", arg1, arg2);
}
/**
* Less than or equal (arg1 <= arg2)
*/
public SQLWhere LE(String arg1, String arg2){
return cond("<=", arg1, arg2);
}
/**
* Greater than or equal (arg1 >= arg2)
*/
public SQLWhere GE(String arg1, String arg2){
return cond(">=", arg1, arg2);
}
private SQLWhere cond(String cond, String arg1, String arg2){
conds.add(
//new StringBuilder(arg1).append(cond).append('\"').append(arg2).append('\"').toString());
new StringBuilder(arg1).append(cond).append(arg2).toString());
return this;
}
public SQLGroupBy GROUP_BY( String ...cols ){
return (SQLGroupBy) (next = new SQLGroupBy(root, cols));
}
public SQLOrderBy ORDER_BY( String ...cols ){
return (SQLOrderBy) (next = new SQLOrderBy(root, cols));
}
public SQLLimit LIMIT( long count ){
return (SQLLimit) (next = new SQLLimit(root, count));
}
protected void build(StringBuilder query) {
query.append(" WHERE ");
if( conds.isEmpty() )
throw new RuntimeException("The WHERE query item must hav atleast 1 condition!");
for(int i=0; i<conds.size() ;i++){
query.append(conds.get(i));
if( i != conds.size()-1 )
query.append(" AND ");
}
if( next != null ) next.build( query );
}
}
//*******************************************
// Sorting Types
public abstract static class SQLGroupOrderBy<T> extends SQLQueryItem{
protected String[] cols;
protected String end;
SQLQueryItem next;
protected SQLGroupOrderBy(SQLQueryItem root, String ...cols){
setRoot(root);
this.cols = cols;
}
@SuppressWarnings("unchecked")
public T ASC(){
end = "ASC";
return (T)this;
}
@SuppressWarnings("unchecked")
public T DESC(){
end = "DESC";
return (T)this;
}
protected void build(String op, StringBuilder query) {
query.append(' ').append(op).append(' ');
if( cols == null || cols.length <= 0 )
throw new RuntimeException("The "+op+" query item must hav atleast 1 column!");
for(int i=0; i<cols.length ;i++){
query.append( cols[i] );
if( i != cols.length-1 )
query.append(",");
}
if( end != null ) query.append(' ').append( end );
if( next != null ) next.build( query );
}
}
public static class SQLGroupBy extends SQLGroupOrderBy<SQLGroupBy>{
protected SQLGroupBy(SQLQueryItem root, String ...cols){
super( root, cols );
}
public SQLOrderBy ORDER_BY( String ...cols ){
return (SQLOrderBy) (next = new SQLOrderBy(root, cols));
}
public SQLLimit LIMIT( long count ){
return (SQLLimit) (next = new SQLLimit(root, count));
}
protected void build(StringBuilder query) {
build("GROUP BY", query);
}
}
public static class SQLOrderBy extends SQLGroupOrderBy<SQLOrderBy>{
protected SQLOrderBy(SQLQueryItem root, String ...cols){
super( root, cols );
}
public SQLLimit LIMIT( long count ){
return (SQLLimit) (next = new SQLLimit(root, count));
}
protected void build(StringBuilder query) {
build("ORDER BY", query);
}
}
public static class SQLLimit extends SQLQueryItem{
long start;
Long count;
protected SQLLimit(SQLQueryItem root, long start){
setRoot( root );
this.start = start;
}
public SQLLimit TO( long count ){
this.count = count;
return this;
}
protected void build(StringBuilder query) {
query.append(" LIMIT ").append( start );
if( count != null ) query.append(' ').append( count );
}
}
//*******************************************
public static SQLSelect SELECT( String ...params ){
return new SQLSelect( params );
}
public static SQLUpdate UPDATE(){
return new SQLUpdate();
}
public static SQLInsert INSERT(){
return new SQLInsert();
}
public static SQLDelete DELETE(){
return new SQLDelete();
}
protected SQLFrom(SQLQueryItem root, String ...tables){
setRoot(root);
for( String table : tables )
this.tables.add(table);
}
public SQLFrom NATURAL_JOIN(String table){
return joinLastTable("NATURAL JOIN", table);
}
public SQLFrom NATURAL_JOIN(String ...tables){
return joinTable("NATURAL JOIN", tables);
}
public SQLFrom JOIN(String table){
return joinLastTable("JOIN", table);
}
public SQLFrom JOIN(String ...tables){
return joinTable("JOIN", tables);
}
public SQLFrom UNION(String table){
return joinLastTable("UNION", table);
}
public SQLFrom UNION(String ...tables){
return joinTable("UNION", tables);
}
private SQLFrom joinLastTable(String type, String table){
String last = tables.getLast();
tables.removeLast();
tables.add(
new StringBuilder(last).append(" ").append(type).append(" ").append(table).toString());
return this;
}
private SQLFrom joinTable(String type, String[] tables){
if( tables.length < 2 )
return this;
StringBuilder str = new StringBuilder();
for(int i=0; i<tables.length ;i++){
str.append(tables[i]);
if( i != tables.length-1 )
str.append(' ').append(type).append(' ');
}
this.tables.add(str.toString());
return this;
}
public SQLWhere WHERE(){
return (SQLWhere) (next = new SQLWhere(root));
}
public SQLGroupBy GROUP_BY( String ...cols ){
return (SQLGroupBy) (next = new SQLGroupBy(root, cols));
}
public SQLOrderBy ORDER_BY( String ...cols ){
return (SQLOrderBy) (next = new SQLOrderBy(root, cols));
}
public SQLLimit LIMIT( long count ){
return (SQLLimit) (next = new SQLLimit(root, count));
}
protected void build(StringBuilder query) {
query.append(" FROM ");
if( tables.isEmpty() )
throw new RuntimeException("The FROM query item must have at least 1 table!");
for(int i=0; i<tables.size() ;i++){
query.append(tables.get(i));
if( i != tables.size()-1 )
query.append(", ");
}
if( next != null ) next.build( query );
}
}
//*******************************************
// Condition Types
public static class SQLWhere extends SQLQueryItem{
LinkedList<String> conds = new LinkedList<String>();
SQLQueryItem next;
protected SQLWhere(SQLQueryItem root){
setRoot(root);
}
/**
* Equals (arg1 = arg2)
*/
public SQLWhere EQ(String arg1, String arg2){
return cond("=", arg1, arg2);
}
/**
* Not Equal (arg1 != arg2)
*/
public SQLWhere NE(String arg1, String arg2){
return cond("!=", arg1, arg2);
}
/**
* Less than (arg1 < arg2)
*/
public SQLWhere LT(String arg1, String arg2){
return cond("<", arg1, arg2);
}
/**
* Greater than (arg1 > arg2)
*/
public SQLWhere GT(String arg1, String arg2){
return cond(">", arg1, arg2);
}
/**
* Less than or equal (arg1 <= arg2)
*/
public SQLWhere LE(String arg1, String arg2){
return cond("<=", arg1, arg2);
}
/**
* Greater than or equal (arg1 >= arg2)
*/
public SQLWhere GE(String arg1, String arg2){
return cond(">=", arg1, arg2);
}
private SQLWhere cond(String cond, String arg1, String arg2){
conds.add(
//new StringBuilder(arg1).append(cond).append('\"').append(arg2).append('\"').toString());
new StringBuilder(arg1).append(cond).append(arg2).toString());
return this;
}
public SQLGroupBy GROUP_BY( String ...cols ){
return (SQLGroupBy) (next = new SQLGroupBy(root, cols));
}
public SQLOrderBy ORDER_BY( String ...cols ){
return (SQLOrderBy) (next = new SQLOrderBy(root, cols));
}
public SQLLimit LIMIT( long count ){
return (SQLLimit) (next = new SQLLimit(root, count));
}
protected void build(StringBuilder query) {
query.append(" WHERE ");
if( conds.isEmpty() )
throw new RuntimeException("The WHERE query item must hav atleast 1 condition!");
for(int i=0; i<conds.size() ;i++){
query.append(conds.get(i));
if( i != conds.size()-1 )
query.append(" AND ");
}
if( next != null ) next.build( query );
}
}
//*******************************************
// Sorting Types
public abstract static class SQLGroupOrderBy<T> extends SQLQueryItem{
protected String[] cols;
protected String end;
SQLQueryItem next;
protected SQLGroupOrderBy(SQLQueryItem root, String ...cols){
setRoot(root);
this.cols = cols;
}
@SuppressWarnings("unchecked")
public T ASC(){
end = "ASC";
return (T)this;
}
@SuppressWarnings("unchecked")
public T DESC(){
end = "DESC";
return (T)this;
}
protected void build(String op, StringBuilder query) {
query.append(' ').append(op).append(' ');
if( cols == null || cols.length <= 0 )
throw new RuntimeException("The "+op+" query item must hav atleast 1 column!");
for(int i=0; i<cols.length ;i++){
query.append( cols[i] );
if( i != cols.length-1 )
query.append(",");
}
if( end != null ) query.append(' ').append( end );
if( next != null ) next.build( query );
}
}
public static class SQLGroupBy extends SQLGroupOrderBy<SQLGroupBy>{
protected SQLGroupBy(SQLQueryItem root, String ...cols){
super( root, cols );
}
public SQLOrderBy ORDER_BY( String ...cols ){
return (SQLOrderBy) (next = new SQLOrderBy(root, cols));
}
public SQLLimit LIMIT( long count ){
return (SQLLimit) (next = new SQLLimit(root, count));
}
protected void build(StringBuilder query) {
build("GROUP BY", query);
}
}
public static class SQLOrderBy extends SQLGroupOrderBy<SQLOrderBy>{
protected SQLOrderBy(SQLQueryItem root, String ...cols){
super( root, cols );
}
public SQLLimit LIMIT( long count ){
return (SQLLimit) (next = new SQLLimit(root, count));
}
protected void build(StringBuilder query) {
build("ORDER BY", query);
}
}
public static class SQLLimit extends SQLQueryItem{
long start;
Long count;
protected SQLLimit(SQLQueryItem root, long start){
setRoot( root );
this.start = start;
}
public SQLLimit TO( long count ){
this.count = count;
return this;
}
protected void build(StringBuilder query) {
query.append(" LIMIT ").append( start );
if( count != null ) query.append(' ').append( count );
}
}
//*******************************************
public static SQLSelect SELECT( String ...params ){
return new SQLSelect( params );
}
public static SQLUpdate UPDATE(){
return new SQLUpdate();
}
public static SQLInsert INSERT(){
return new SQLInsert();
}
public static SQLDelete DELETE(){
return new SQLDelete();
}
}

View file

@ -29,11 +29,11 @@ import java.sql.SQLException;
import java.sql.Statement;
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 handleQueryResult(Statement stmt, ResultSet result) throws SQLException;
/**
* Is called to handle an result from an query.
*
* @param stmt is the query
* @param result is the ResultSet
*/
public T handleQueryResult(Statement stmt, ResultSet result) throws SQLException;
}

View file

@ -40,7 +40,7 @@ class DBBeanConfig{
private static HashMap<String,DBBeanConfig> beanConfigs = new HashMap<>();
/** The name of the table in the DB **/
/** The name of the table in the DB **/
private String tableName;
/** The name of the id column **/
private String idColumnName;

View file

@ -39,111 +39,111 @@ import java.util.logging.Logger;
public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
private static final Logger logger = LogUtil.getLogger();
private Class<? extends DBBean> beanClass;
private DBBeanConfig beanConfig;
private DBConnection db;
private boolean list;
private static final Logger logger = LogUtil.getLogger();
private Class<? extends DBBean> beanClass;
private DBBeanConfig beanConfig;
private DBConnection db;
private boolean list;
/**
* Creates a new instance of this class that returns only one bean
*
* @param cl is the DBBean class that will be parsed from the SQL result
* @return a new instance of this class
*/
public static <C extends DBBean> DBBeanSQLResultHandler<C> create(Class<C> cl){
return new DBBeanSQLResultHandler<>(cl, null, false);
}
/**
* Creates a new instance of this class that returns only one bean
*
* @param cl is the DBBean class that will be parsed from the SQL result
* @return a new instance of this class
*/
public static <C extends DBBean> DBBeanSQLResultHandler<C> create(Class<C> cl){
return new DBBeanSQLResultHandler<>(cl, null, false);
}
/**
* Creates a new instance of this class that returns a bean with all its containing beans
*
* @param cl is the DBBean class that will be parsed from the SQL result
* @param db is the DB connection for loading internal beans
* @return a new instance of this class
*/
public static <C extends DBBean> DBBeanSQLResultHandler<C> create(Class<C> cl, DBConnection db){
return new DBBeanSQLResultHandler<>(cl, db, false);
}
/**
* Creates a new instance of this class that returns a bean with all its containing beans
*
* @param cl is the DBBean class that will be parsed from the SQL result
* @param db is the DB connection for loading internal beans
* @return a new instance of this class
*/
public static <C extends DBBean> DBBeanSQLResultHandler<C> create(Class<C> cl, DBConnection db){
return new DBBeanSQLResultHandler<>(cl, db, false);
}
/**
* Creates a new instance of this class that returns a list of beans
*
* @param cl is the DBBean class that will be parsed from the SQL result
* @return a new instance of this class
*/
public static <C extends DBBean> DBBeanSQLResultHandler<List<C>> createList(Class<C> cl){
return new DBBeanSQLResultHandler<>(cl, null, true);
}
/**
* Creates a new instance of this class that returns a list of beans
*
* @param cl is the DBBean class that will be parsed from the SQL result
* @return a new instance of this class
*/
public static <C extends DBBean> DBBeanSQLResultHandler<List<C>> createList(Class<C> cl){
return new DBBeanSQLResultHandler<>(cl, null, true);
}
/**
* Creates a new instance of this class that returns a list of beans with all the internal beans
*
* @param cl is the DBBean class that will be parsed from the SQL result
* @param db is the DB connection for loading internal beans
* @return a new instance of this class
*/
public static <C extends DBBean> DBBeanSQLResultHandler<List<C>> createList(Class<C> cl, DBConnection db){
return new DBBeanSQLResultHandler<>(cl, db, true);
}
/**
* Creates a new instance of this class that returns a list of beans with all the internal beans
*
* @param cl is the DBBean class that will be parsed from the SQL result
* @param db is the DB connection for loading internal beans
* @return a new instance of this class
*/
public static <C extends DBBean> DBBeanSQLResultHandler<List<C>> createList(Class<C> cl, DBConnection db){
return new DBBeanSQLResultHandler<>(cl, db, true);
}
/**
* Creates a new instance of this class
*
* @param cl is the DBBean class that will be parsed from the SQL result
* @param db is the DB connection for loading internal beans, may be null to disable internal beans
* @param list is if the handler should return a list of beans instead of one
*/
protected DBBeanSQLResultHandler(Class<? extends DBBean> cl, DBConnection db, boolean list) {
this.beanClass = cl;
this.list = list;
this.db = db;
this.beanConfig = DBBeanConfig.getBeanConfig( cl );
}
/**
* Creates a new instance of this class
*
* @param cl is the DBBean class that will be parsed from the SQL result
* @param db is the DB connection for loading internal beans, may be null to disable internal beans
* @param list is if the handler should return a list of beans instead of one
*/
protected DBBeanSQLResultHandler(Class<? extends DBBean> cl, DBConnection db, boolean list) {
this.beanClass = cl;
this.list = list;
this.db = db;
this.beanConfig = DBBeanConfig.getBeanConfig( cl );
}
/**
* Is called to handle a result from a query.
*
* @param stmt is the query
* @param result is the ResultSet
*/
@SuppressWarnings("unchecked")
public T handleQueryResult(Statement stmt, ResultSet result) throws SQLException{
if( list ){
List<DBBean> bean_list = new LinkedList<>();
while( result.next() ){
DBBean obj = createBean(result);
bean_list.add( obj );
}
return (T) bean_list;
}
else{
if( result.next() ){
return (T) createBean(result);
}
return null;
}
/**
* Is called to handle a result from a query.
*
* @param stmt is the query
* @param result is the ResultSet
*/
@SuppressWarnings("unchecked")
public T handleQueryResult(Statement stmt, ResultSet result) throws SQLException{
if( list ){
List<DBBean> bean_list = new LinkedList<>();
while( result.next() ){
DBBean obj = createBean(result);
bean_list.add( obj );
}
return (T) bean_list;
}
else{
if( result.next() ){
return (T) createBean(result);
}
return null;
}
}
/**
* Instantiates a new bean and assigns field values from the ResultSet
*
* @param result is where the field values for the bean will bee read from, the cursor should be in front of the data
* @return a new instance of the bean
*/
private DBBean createBean(ResultSet result) throws SQLException{
try {
Long id = result.getLong( "id" );
// Check cache first
DBBean obj = DBBeanCache.get(beanClass, id);
if ( obj == null ) {
}
/**
* Instantiates a new bean and assigns field values from the ResultSet
*
* @param result is where the field values for the bean will bee read from, the cursor should be in front of the data
* @return a new instance of the bean
*/
private DBBean createBean(ResultSet result) throws SQLException{
try {
Long id = result.getLong( "id" );
// Check cache first
DBBean obj = DBBeanCache.get(beanClass, id);
if ( obj == null ) {
// Cache miss create a new bean
logger.fine("Creating new Bean(" + beanClass.getName() + ") with id: " + id);
obj = beanClass.newInstance();
@ -155,23 +155,23 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
logger.finer("Bean(" + beanClass.getName() + ") cache to old for id: " + id);
updateBean(result, obj);
}
return obj;
} catch (SQLException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Updates an existing bean and assigns field values from the ResultSet
*
* @param result is where the field values for the bean will be read from, the cursor should be in front of the data
* @param obj is the bean that will be updated
*/
@SuppressWarnings("unchecked")
private void updateBean(ResultSet result, DBBean obj) throws SQLException{
if (obj.readLock.tryLock()) {
return obj;
} catch (SQLException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Updates an existing bean and assigns field values from the ResultSet
*
* @param result is where the field values for the bean will be read from, the cursor should be in front of the data
* @param obj is the bean that will be updated
*/
@SuppressWarnings("unchecked")
private void updateBean(ResultSet result, DBBean obj) throws SQLException{
if (obj.readLock.tryLock()) {
try {
logger.fine("Updating Bean("+ beanClass.getName() +") with id: "+ obj.getId());
// Read fields
@ -198,25 +198,25 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
DBBeanCache.add(obj);
// Read sub beans
if (db != null) {
for (DBBeanSubBeanConfig subBeanField : beanConfig.getSubBeans()) {
DBBeanConfig subBeanConfig = subBeanField.getSubBeanConfig();
if (db != null) {
for (DBBeanSubBeanConfig subBeanField : beanConfig.getSubBeans()) {
DBBeanConfig subBeanConfig = subBeanField.getSubBeanConfig();
// Load List from link table
String subSql = "SELECT subBeanTable.* FROM "+
// Load List from link table
String subSql = "SELECT subBeanTable.* FROM "+
subBeanField.getLinkTableName() +" as linkTable, "+
subBeanConfig.getTableName() +" as subBeanTable " +
"WHERE linkTable."+subBeanField.getParentIdColumnName()+"=? AND " +
"linkTable."+subBeanConfig.getIdColumnName()+"=subBeanTable."+subBeanConfig.getIdColumnName();
logger.finest("List Load Query: " + subSql);
PreparedStatement subStmt = db.getPreparedStatement(subSql);
subStmt.setObject(1, obj.getId());
List<? extends DBBean> list = DBConnection.exec(subStmt,
DBBeanSQLResultHandler.createList(subBeanField.getSubBeanClass(), db));
logger.finest("List Load Query: " + subSql);
PreparedStatement subStmt = db.getPreparedStatement(subSql);
subStmt.setObject(1, obj.getId());
List<? extends DBBean> list = DBConnection.exec(subStmt,
DBBeanSQLResultHandler.createList(subBeanField.getSubBeanClass(), db));
subBeanField.setValue(obj, list);
}
} else
logger.warning("No DB available to read sub beans");
}
} else
logger.warning("No DB available to read sub beans");
// Call post listener
obj.postUpdateAction();
@ -227,7 +227,7 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
obj.readLock.lock();
obj.readLock.unlock();
}
}
}
}

View file

@ -41,27 +41,27 @@ import java.util.List;
*/
public class ListSQLResult<T> implements SQLResultHandler<List<T>> {
private List<T> list;
private List<T> list;
/**
* Creates a new List.
*/
public ListSQLResult(){
this.list = new ArrayList<>();
}
/**
* Creates a new List.
*/
public ListSQLResult(){
this.list = new ArrayList<>();
}
/**
* Uses a existing list that items will be appended on.
*/
public ListSQLResult(List l){
this.list = l;
}
/**
* Uses a existing list that items will be appended on.
*/
public ListSQLResult(List l){
this.list = l;
}
public List<T> handleQueryResult(Statement stmt, ResultSet result) throws SQLException{
while( result.next() )
list.add((T)result.getObject(1));
return list;
}
public List<T> handleQueryResult(Statement stmt, ResultSet result) throws SQLException{
while( result.next() )
list.add((T)result.getObject(1));
return list;
}
}

View file

@ -40,30 +40,30 @@ import java.util.Properties;
* @author Ziver
*/
public class PropertiesSQLResult implements SQLResultHandler<Properties> {
private Properties prop;
/**
* Creates a new Properties object to be filled
*/
public PropertiesSQLResult(){
this.prop = new Properties();
}
/**
* Adds data to a existing Properties object
*/
public PropertiesSQLResult(Properties p){
this.prop = p;
}
/**
* Is called to handle an result from an query.
*/
public Properties handleQueryResult(Statement stmt, ResultSet result) throws SQLException{
while( result.next() )
prop.setProperty(result.getString(1), result.getString(2));
return prop;
}
private Properties prop;
/**
* Creates a new Properties object to be filled
*/
public PropertiesSQLResult(){
this.prop = new Properties();
}
/**
* Adds data to a existing Properties object
*/
public PropertiesSQLResult(Properties p){
this.prop = p;
}
/**
* Is called to handle an result from an query.
*/
public Properties handleQueryResult(Statement stmt, ResultSet result) throws SQLException{
while( result.next() )
prop.setProperty(result.getString(1), result.getString(2));
return prop;
}
}

View file

@ -36,16 +36,16 @@ import java.sql.Statement;
* @author Ziver
*/
public class SimpleSQLResult<T> implements SQLResultHandler<T> {
/**
* Is called to handle an result from an query.
*
* @param stmt is the query
* @param result is the ResultSet
*/
@SuppressWarnings("unchecked")
public T handleQueryResult(Statement stmt, ResultSet result) throws SQLException{
if( result.next() )
return (T) result.getObject(1);
return null;
}
/**
* Is called to handle an result from an query.
*
* @param stmt is the query
* @param result is the ResultSet
*/
@SuppressWarnings("unchecked")
public T handleQueryResult(Statement stmt, ResultSet result) throws SQLException{
if( result.next() )
return (T) result.getObject(1);
return null;
}
}

View file

@ -37,163 +37,163 @@ import java.awt.image.BufferedImage;
* @author Ziver
*/
public abstract class ImageFilterProcessor {
private BufferedImage img;
private ProgressListener<ImageFilterProcessor,?> progress;
private BufferedImage img;
private ProgressListener<ImageFilterProcessor,?> progress;
public ImageFilterProcessor(BufferedImage img){
this.img = img;
}
/**
* Sets the listener
* @param listener is the listener, null to disable the progress
*/
public void setProgressListener(ProgressListener<ImageFilterProcessor,?> listener){
this.progress = listener;
}
/**
* Returns the listener
*/
public ProgressListener<?,?> getProgressListener(){
return this.progress;
}
/**
* Sets the progress in percent
*/
protected void setProgress(double percent){
if(progress != null) progress.progressUpdate(this, null, percent);
}
/**
* Applies a effect to a given image
*
* @param effect The effect to use
* @param img The image to process
* @return The processed image
*/
public static ImageFilterProcessor getProcessor(String effect, BufferedImage img) throws InstantiationException, IllegalAccessException, ClassNotFoundException, InterruptedException{
ImageFilterProcessor processor = (ImageFilterProcessor)Class.forName(effect).newInstance();
processor.img = img;
return processor;
}
public ImageFilterProcessor(BufferedImage img){
this.img = img;
}
/**
* Adds the chosen effect to the image
*
* @return The Image with the effect
*/
public BufferedImage process() throws InterruptedException{
int cols = img.getWidth();
int rows = img.getHeight();
/**
* Sets the listener
* @param listener is the listener, null to disable the progress
*/
public void setProgressListener(ProgressListener<ImageFilterProcessor,?> listener){
this.progress = listener;
}
if(cols < 0 || rows < 0){
throw new InterruptedException("Image not Loaded!!!");
}
/**
* Returns the listener
*/
public ProgressListener<?,?> getProgressListener(){
return this.progress;
}
// converts the img to raw data
int[][][] data = convertToArray(img, cols, rows);
//processes the image
data = process(data);
//converts back the image
return convertToImage(data, data[0].length, data.length);
}
/**
* Sets the progress in percent
*/
protected void setProgress(double percent){
if(progress != null) progress.progressUpdate(this, null, percent);
}
/**
* Creates a Integer array with the pixel data of the image <XMP>
* int[row][col][4]
* 0 -> Alpha data
* Red data
* Green data
* 4 -> Blue data </XMP>
*
* @param img is the image to convert
* @param cols is the columns of the image
* @param rows is the rows of the image
* @return A is the integer array
*/
public static int[][][] convertToArray(BufferedImage img, int cols, int rows) throws InterruptedException{
int[][][] data = new int[rows][cols][4];
// Reads in the image to a one dim array
int[] pixels = img.getRGB(0, 0, cols, rows, null, 0, cols);
/**
* Applies a effect to a given image
*
* @param effect The effect to use
* @param img The image to process
* @return The processed image
*/
public static ImageFilterProcessor getProcessor(String effect, BufferedImage img) throws InstantiationException, IllegalAccessException, ClassNotFoundException, InterruptedException{
ImageFilterProcessor processor = (ImageFilterProcessor)Class.forName(effect).newInstance();
processor.img = img;
return processor;
}
// Read the pixel data and put it in the data array
for(int y=0; y<rows ;y++){
// reading a row
int[] aRow = new int[cols];
for(int x=0; x<cols ;x++){
int element = y * cols + x;
aRow[x] = pixels[element];
}
/**
* Adds the chosen effect to the image
*
* @return The Image with the effect
*/
public BufferedImage process() throws InterruptedException{
int cols = img.getWidth();
int rows = img.getHeight();
// Reading in the color data
for(int x=0; x<cols ;x++){
//Alpha data
data[y][x][0] = ((aRow[x] >> 24) & 0xFF);
//Red data
data[y][x][1] = ((aRow[x] >> 16) & 0xFF);
//Green data
data[y][x][2] = ((aRow[x] >> 8) & 0xFF);
//Blue data
data[y][x][3] = ((aRow[x])& 0xFF);
}
}
return data;
}
if(cols < 0 || rows < 0){
throw new InterruptedException("Image not Loaded!!!");
}
// converts the img to raw data
int[][][] data = convertToArray(img, cols, rows);
//processes the image
data = process(data);
//converts back the image
return convertToImage(data, data[0].length, data.length);
}
/**
* Creates a Integer array with the pixel data of the image <XMP>
* int[row][col][4]
* 0 -> Alpha data
* Red data
* Green data
* 4 -> Blue data </XMP>
*
* @param img is the image to convert
* @param cols is the columns of the image
* @param rows is the rows of the image
* @return A is the integer array
*/
public static int[][][] convertToArray(BufferedImage img, int cols, int rows) throws InterruptedException{
int[][][] data = new int[rows][cols][4];
// Reads in the image to a one dim array
int[] pixels = img.getRGB(0, 0, cols, rows, null, 0, cols);
// Read the pixel data and put it in the data array
for(int y=0; y<rows ;y++){
// reading a row
int[] aRow = new int[cols];
for(int x=0; x<cols ;x++){
int element = y * cols + x;
aRow[x] = pixels[element];
}
// Reading in the color data
for(int x=0; x<cols ;x++){
//Alpha data
data[y][x][0] = ((aRow[x] >> 24) & 0xFF);
//Red data
data[y][x][1] = ((aRow[x] >> 16) & 0xFF);
//Green data
data[y][x][2] = ((aRow[x] >> 8) & 0xFF);
//Blue data
data[y][x][3] = ((aRow[x])& 0xFF);
}
}
return data;
}
/**
* Converts a pixel data array to a java Image object
*
* @param pixels is the pixel data array
* @param cols is the columns of the image
* @param rows is the rows of the image
* @return A Image
*/
public static BufferedImage convertToImage(int[][][] pixels, int cols, int rows){
int[] data = new int[cols * rows * 4];
/**
* Converts a pixel data array to a java Image object
*
* @param pixels is the pixel data array
* @param cols is the columns of the image
* @param rows is the rows of the image
* @return A Image
*/
public static BufferedImage convertToImage(int[][][] pixels, int cols, int rows){
int[] data = new int[cols * rows * 4];
//Move the data into the 1D array. Note the
// use of the bitwise OR operator and the
// bitwise left-shift operators to put the
// four 8-bit bytes into each int.
int index = 0;
for(int y=0; y<rows ;y++){
for(int x=0; x< cols ;x++){
data[index] = ((pixels[y][x][0] << 24) & 0xFF000000)
| ((pixels[y][x][1] << 16) & 0x00FF0000)
| ((pixels[y][x][2] << 8) & 0x0000FF00)
| ((pixels[y][x][3]) & 0x000000FF);
index++;
}
//Move the data into the 1D array. Note the
// use of the bitwise OR operator and the
// bitwise left-shift operators to put the
// four 8-bit bytes into each int.
int index = 0;
for(int y=0; y<rows ;y++){
for(int x=0; x< cols ;x++){
data[index] = ((pixels[y][x][0] << 24) & 0xFF000000)
| ((pixels[y][x][1] << 16) & 0x00FF0000)
| ((pixels[y][x][2] << 8) & 0x0000FF00)
| ((pixels[y][x][3]) & 0x000000FF);
index++;
}
}
}
BufferedImage img = new BufferedImage(cols, rows, BufferedImage.TYPE_4BYTE_ABGR);
img.setRGB(0, 0, cols, rows, data, 0, cols);
BufferedImage img = new BufferedImage(cols, rows, BufferedImage.TYPE_4BYTE_ABGR);
img.setRGB(0, 0, cols, rows, data, 0, cols);
return img;
}
return img;
}
/**
* Runs the image thru the processor
*
* @param data is the raw image to apply the effect to. This will NOT be altered
*/
public int[][][] process(int[][][] data){
return process(data, 0, 0, data[0].length, data.length);
}
/**
* The underlying effect is run here
*
* @param data is the raw image to apply the effect to. This will NOT be altered
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @return either the modified data parameter or an new array
*/
public abstract int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY);
/**
* Runs the image thru the processor
*
* @param data is the raw image to apply the effect to. This will NOT be altered
*/
public int[][][] process(int[][][] data){
return process(data, 0, 0, data[0].length, data.length);
}
/**
* The underlying effect is run here
*
* @param data is the raw image to apply the effect to. This will NOT be altered
* @param startX is the x pixel of the image to start from
* @param startY is the y pixel of the image to start from
* @param stopX is the x pixel of the image to stop
* @param stopY is the y pixel of the image to stop
* @return either the modified data parameter or an new array
*/
public abstract int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY);
}

View file

@ -35,81 +35,81 @@ import java.awt.image.BufferedImage;
*/
public class ImageUtil {
/**
* Resizes a BufferedImage
*
* @param source is the image to resize
* @param width is the wanted width
* @param height is the wanted height
* @param keep_aspect is if the aspect ratio of the image should be kept
* @return the resized image
*/
public static BufferedImage scale(BufferedImage source, int width, int height, boolean keep_aspect){
double scale_width = (double)width / source.getWidth();
double scale_height = (double)height / source.getHeight();
/**
* Resizes a BufferedImage
*
* @param source is the image to resize
* @param width is the wanted width
* @param height is the wanted height
* @param keep_aspect is if the aspect ratio of the image should be kept
* @return the resized image
*/
public static BufferedImage scale(BufferedImage source, int width, int height, boolean keep_aspect){
double scale_width = (double)width / source.getWidth();
double scale_height = (double)height / source.getHeight();
// aspect calculation
if(keep_aspect){
if(scale_width * source.getHeight() > height){
scale_width = scale_height;
}else{
scale_height = scale_width;
}
}
// aspect calculation
if(keep_aspect){
if(scale_width * source.getHeight() > height){
scale_width = scale_height;
}else{
scale_height = scale_width;
}
}
BufferedImage tmp = new BufferedImage(
(int)(scale_width * source.getWidth()),
(int)(scale_height * source.getHeight()),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = tmp.createGraphics();
BufferedImage tmp = new BufferedImage(
(int)(scale_width * source.getWidth()),
(int)(scale_height * source.getHeight()),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = tmp.createGraphics();
AffineTransform at = AffineTransform.getScaleInstance(scale_width, scale_height);
g2d.drawRenderedImage(source, at);
g2d.dispose();
return tmp;
}
AffineTransform at = AffineTransform.getScaleInstance(scale_width, scale_height);
g2d.drawRenderedImage(source, at);
g2d.dispose();
return tmp;
}
/**
* Crops a image to a specific aspect ration
*
* @param image is the actual image to crop
* @param aspect is the aspect ratio to convert the image to
* @return a new image with the specified aspect ratio
*/
public static BufferedImage cropToAspectRatio(BufferedImage image, float aspect){
int x = 0, y = 0;
int width = image.getWidth();
int height = image.getHeight();
/**
* Crops a image to a specific aspect ration
*
* @param image is the actual image to crop
* @param aspect is the aspect ratio to convert the image to
* @return a new image with the specified aspect ratio
*/
public static BufferedImage cropToAspectRatio(BufferedImage image, float aspect){
int x = 0, y = 0;
int width = image.getWidth();
int height = image.getHeight();
// Check if the width is larger than the heigth
if( width > height ){
width = (int) (height * aspect);
x = image.getWidth()/2 - width/2;
}
else{
height = (int) (width * aspect);
y = image.getHeight()/2 - height/2;
}
// Check if the width is larger than the heigth
if( width > height ){
width = (int) (height * aspect);
x = image.getWidth()/2 - width/2;
}
else{
height = (int) (width * aspect);
y = image.getHeight()/2 - height/2;
}
return image.getSubimage(x, y, width, height);
}
return image.getSubimage(x, y, width, height);
}
/**
* This function crops the image to the aspect ratio of
* the width and height and then scales the image to the
* given values
*
* @param source is the image to resize
* @param width is the wanted width
* @param height is the wanted height
* @return a new image with the specified width and height
*/
public static BufferedImage cropScale(BufferedImage source, int width, int height){
float aspect = width/height;
BufferedImage tmp = cropToAspectRatio(source, aspect);
tmp = scale(tmp, width, height, false);
return tmp;
}
/**
* This function crops the image to the aspect ratio of
* the width and height and then scales the image to the
* given values
*
* @param source is the image to resize
* @param width is the wanted width
* @param height is the wanted height
* @return a new image with the specified width and height
*/
public static BufferedImage cropScale(BufferedImage source, int width, int height){
float aspect = width/height;
BufferedImage tmp = cropToAspectRatio(source, aspect);
tmp = scale(tmp, width, height, false);
return tmp;
}
}

View file

@ -31,87 +31,87 @@ import zutil.math.ZMath;
import java.awt.image.BufferedImage;
public class BlurFilter extends ImageFilterProcessor{
private int blurValue;
private int blurValue;
/**
* Creates a blur effect on the image
* @param img The image to blur
*/
public BlurFilter(BufferedImage img){
this(img, 10);
}
/**
* Creates a blur effect on the image
* @param img The image to blur
*/
public BlurFilter(BufferedImage img){
this(img, 10);
}
/**
* Creates a blur effect on the image
* @param img The image to blur
* @param blur The amount to blur
*/
public BlurFilter(BufferedImage img, int blur){
super(img);
blurValue = blur;
}
/**
* Creates a blur effect on the image
* @param img The image to blur
* @param blur The amount to blur
*/
public BlurFilter(BufferedImage img, int blur){
super(img);
blurValue = blur;
}
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int inputPeak = RAWImageUtil.getPeakValue(data);
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int inputPeak = RAWImageUtil.getPeakValue(data);
int[][][] tmpData = new int[data.length][data[0].length][4];
int[][][] output = RAWImageUtil.copyArray(data);
//Perform the convolution one or more times in succession
int redSum, greenSum, blueSum, outputPeak;
for(int i=0; i<blurValue ;i++){
//Iterate on each pixel as a registration point.
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, (blurValue-1)*(stopY-startY-2), i*(stopY-startY-2)+y));
for(int x=startX; x<stopX ;x++){
if(x == 0 || x == output[0].length-1 || y == 0 || y == output.length-1){
redSum = output[y][x][1] * 9;
greenSum = output[y][x][2] * 9;
blueSum = output[y][x][3] * 9;
}
else{
redSum =
output[y - 1][x - 1][1] +
output[y - 1][x - 0][1] +
output[y - 1][x + 1][1] +
output[y - 0][x - 1][1] +
output[y - 0][x - 0][1] +
output[y - 0][x + 1][1] +
output[y + 1][x - 1][1] +
output[y + 1][x - 0][1] +
output[y + 1][x + 1][1];
greenSum =
output[y - 1][x - 1][2] +
output[y - 1][x - 0][2] +
output[y - 1][x + 1][2] +
output[y - 0][x - 1][2] +
output[y - 0][x - 0][2] +
output[y - 0][x + 1][2] +
output[y + 1][x - 1][2] +
output[y + 1][x - 0][2] +
output[y + 1][x + 1][2];
blueSum =
output[y - 1][x - 1][3] +
output[y - 1][x - 0][3] +
output[y - 1][x + 1][3] +
output[y - 0][x - 1][3] +
output[y - 0][x - 0][3] +
output[y - 0][x + 1][3] +
output[y + 1][x - 1][3] +
output[y + 1][x - 0][3] +
output[y + 1][x + 1][3];
}
tmpData[y][x][0] = output[y][x][0];
tmpData[y][x][1] = redSum;
tmpData[y][x][2] = greenSum;
tmpData[y][x][3] = blueSum;
}
}
int[][][] tmpData = new int[data.length][data[0].length][4];
int[][][] output = RAWImageUtil.copyArray(data);
//Perform the convolution one or more times in succession
int redSum, greenSum, blueSum, outputPeak;
for(int i=0; i<blurValue ;i++){
//Iterate on each pixel as a registration point.
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, (blurValue-1)*(stopY-startY-2), i*(stopY-startY-2)+y));
for(int x=startX; x<stopX ;x++){
if(x == 0 || x == output[0].length-1 || y == 0 || y == output.length-1){
redSum = output[y][x][1] * 9;
greenSum = output[y][x][2] * 9;
blueSum = output[y][x][3] * 9;
}
else{
redSum =
output[y - 1][x - 1][1] +
output[y - 1][x - 0][1] +
output[y - 1][x + 1][1] +
output[y - 0][x - 1][1] +
output[y - 0][x - 0][1] +
output[y - 0][x + 1][1] +
output[y + 1][x - 1][1] +
output[y + 1][x - 0][1] +
output[y + 1][x + 1][1];
greenSum =
output[y - 1][x - 1][2] +
output[y - 1][x - 0][2] +
output[y - 1][x + 1][2] +
output[y - 0][x - 1][2] +
output[y - 0][x - 0][2] +
output[y - 0][x + 1][2] +
output[y + 1][x - 1][2] +
output[y + 1][x - 0][2] +
output[y + 1][x + 1][2];
blueSum =
output[y - 1][x - 1][3] +
output[y - 1][x - 0][3] +
output[y - 1][x + 1][3] +
output[y - 0][x - 1][3] +
output[y - 0][x - 0][3] +
output[y - 0][x + 1][3] +
output[y + 1][x - 1][3] +
output[y + 1][x - 0][3] +
output[y + 1][x + 1][3];
}
tmpData[y][x][0] = output[y][x][0];
tmpData[y][x][1] = redSum;
tmpData[y][x][2] = greenSum;
tmpData[y][x][3] = blueSum;
}
}
// getting the new peak value and normalizing the image
outputPeak = RAWImageUtil.getPeakValue(tmpData);
RAWImageUtil.normalize(output, tmpData, startX, startY, stopX, stopY, ((double)inputPeak)/outputPeak );
}
return output;
}
// getting the new peak value and normalizing the image
outputPeak = RAWImageUtil.getPeakValue(tmpData);
RAWImageUtil.normalize(output, tmpData, startX, startY, stopX, stopY, ((double)inputPeak)/outputPeak );
}
return output;
}
}

View file

@ -30,84 +30,84 @@ import zutil.math.ZMath;
import java.awt.image.BufferedImage;
public class ColorIntensityFilter extends ImageFilterProcessor{
private boolean invert;
private double redScale;
private double greenScale;
private double blueScale;
private boolean invert;
private double redScale;
private double greenScale;
private double blueScale;
public ColorIntensityFilter(BufferedImage img){
this(img, 0.2, 0.2, 0.2, false);
}
public ColorIntensityFilter(BufferedImage img){
this(img, 0.2, 0.2, 0.2, false);
}
/**
* Creates a ColorIntensityEffect object with the given values
* @param img The image data
* @param inv If the image color should be inverted
*/
public ColorIntensityFilter(BufferedImage img, boolean inv){
this(img, 0.5, 0.5, 0.5, inv);
}
/**
* Creates a ColorIntensityEffect object with the given values
* @param img The image data
* @param inv If the image color should be inverted
*/
public ColorIntensityFilter(BufferedImage img, boolean inv){
this(img, 0.5, 0.5, 0.5, inv);
}
/**
* Creates a ColorIntensityEffect object with the given values
* @param img The image data
* @param red The scale of red (0-1)
* @param green The scale of green (0-1)
* @param blue The scale of blue (0-1)
*/
public ColorIntensityFilter(BufferedImage img, double red, double green, double blue){
this(img, red, green, blue, false);
}
/**
* Creates a ColorIntensityEffect object with the given values
* @param img The image data
* @param red The scale of red (0-1)
* @param green The scale of green (0-1)
* @param blue The scale of blue (0-1)
*/
public ColorIntensityFilter(BufferedImage img, double red, double green, double blue){
this(img, red, green, blue, false);
}
/**
* Creates a ColorIntensityEffect object with the given values
* @param img The image data
* @param red The scale of red (0-1)
* @param green The scale of green (0-1)
* @param blue The scale of blue (0-1)
* @param inv If the image color should be inverted
*/
public ColorIntensityFilter(BufferedImage img, double red, double green, double blue, boolean inv){
super(img);
invert = false;
redScale = red;
greenScale = green;
blueScale = blue;
}
/**
* Creates a ColorIntensityEffect object with the given values
* @param img The image data
* @param red The scale of red (0-1)
* @param green The scale of green (0-1)
* @param blue The scale of blue (0-1)
* @param inv If the image color should be inverted
*/
public ColorIntensityFilter(BufferedImage img, double red, double green, double blue, boolean inv){
super(img);
invert = false;
redScale = red;
greenScale = green;
blueScale = blue;
}
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int[][][] output = new int[data.length][data[0].length][4];
// making sure the scales are right
if(redScale > 1) redScale = 1;
else if(redScale < 0) redScale = 0;
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int[][][] output = new int[data.length][data[0].length][4];
// making sure the scales are right
if(redScale > 1) redScale = 1;
else if(redScale < 0) redScale = 0;
if(greenScale > 1) greenScale = 1;
else if(greenScale < 0) greenScale = 0;
if(greenScale > 1) greenScale = 1;
else if(greenScale < 0) greenScale = 0;
if(blueScale > 1) blueScale = 1;
else if(blueScale < 0) blueScale = 0;
// Applying the color intensity to the image
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, stopY-startY-1, y));
for(int x=startX; x<stopX ;x++){
if(!invert){
// inversion
output[y][x][0] = data[y][x][0];
output[y][x][1] = (int)( 255 - data[y][x][1] * redScale );
output[y][x][2] = (int)( 255 - data[y][x][2] * greenScale );
output[y][x][3] = (int)( 255 - data[y][x][3] * blueScale );
}
else{
output[y][x][0] = data[y][x][0];
output[y][x][1] = (int)( data[y][x][1] * redScale );
output[y][x][2] = (int)( data[y][x][2] * greenScale );
output[y][x][3] = (int)( data[y][x][3] * blueScale );
}
}
}
return output;
}
if(blueScale > 1) blueScale = 1;
else if(blueScale < 0) blueScale = 0;
// Applying the color intensity to the image
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, stopY-startY-1, y));
for(int x=startX; x<stopX ;x++){
if(!invert){
// inversion
output[y][x][0] = data[y][x][0];
output[y][x][1] = (int)( 255 - data[y][x][1] * redScale );
output[y][x][2] = (int)( 255 - data[y][x][2] * greenScale );
output[y][x][3] = (int)( 255 - data[y][x][3] * blueScale );
}
else{
output[y][x][0] = data[y][x][0];
output[y][x][1] = (int)( data[y][x][1] * redScale );
output[y][x][2] = (int)( data[y][x][2] * greenScale );
output[y][x][3] = (int)( data[y][x][3] * blueScale );
}
}
}
return output;
}
}

View file

@ -30,42 +30,42 @@ import zutil.image.RAWImageUtil;
import java.awt.image.BufferedImage;
public class ContrastBrightnessFilter extends ImageFilterProcessor{
private double contrast;
private double brightness;
private double contrast;
private double brightness;
/**
* Creates a ContrastBrightnessEffect object with the given values
* @param img The image to apply the effect to
*/
public ContrastBrightnessFilter(BufferedImage img){
this(img, 3, 1.2);
}
/**
* Creates a ContrastBrightnessEffect object with the given values
* @param img The image to apply the effect to
*/
public ContrastBrightnessFilter(BufferedImage img){
this(img, 3, 1.2);
}
/**
* Creates a ContrastBrightnessEffect object with the given values
* @param img The image to apply the effect to
* @param con The contrast to apply
* @param brig The brightness to apply
*/
public ContrastBrightnessFilter(BufferedImage img, double con, double brig){
super(img);
contrast = con;
brightness = brig;
}
/**
* Creates a ContrastBrightnessEffect object with the given values
* @param img The image to apply the effect to
* @param con The contrast to apply
* @param brig The brightness to apply
*/
public ContrastBrightnessFilter(BufferedImage img, double con, double brig){
super(img);
contrast = con;
brightness = brig;
}
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int mean = RAWImageUtil.getMeanValue(data);
int[][][] output = RAWImageUtil.copyArray(data);
RAWImageUtil.addMeanValue(output, startX, startY, stopX, stopY, mean*(-1));
RAWImageUtil.scale(output, startX, startY, stopX, stopY, contrast);
RAWImageUtil.addMeanValue(output, startX, startY, stopX, stopY, (int)(brightness*mean));
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int mean = RAWImageUtil.getMeanValue(data);
RAWImageUtil.clip(output, startX, startY, stopX, stopY);
return output;
}
int[][][] output = RAWImageUtil.copyArray(data);
RAWImageUtil.addMeanValue(output, startX, startY, stopX, stopY, mean*(-1));
RAWImageUtil.scale(output, startX, startY, stopX, stopY, contrast);
RAWImageUtil.addMeanValue(output, startX, startY, stopX, stopY, (int)(brightness*mean));
RAWImageUtil.clip(output, startX, startY, stopX, stopY);
return output;
}
}

View file

@ -36,72 +36,72 @@ import java.awt.image.BufferedImage;
* @author Ziver
*/
public class ConvolutionFilter extends ImageFilterProcessor{
private double[][] kernel;
private double[][] kernel;
protected ConvolutionFilter(BufferedImage img) {
super(img);
}
public ConvolutionFilter(double[][] kernel) {
this(null, kernel);
}
/**
* Applies an Convolution kernel to the specified image
*
* @param img is the image
* @param kernel is the kernel to apply to the image
*/
public ConvolutionFilter(BufferedImage img, double[][] kernel) {
super(img);
this.kernel = kernel;
}
protected ConvolutionFilter(BufferedImage img) {
super(img);
}
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
if(kernel == null) this.kernel = generateKernel();
int[][][] tmpData = new int[data.length][data[0].length][4];
int xk_length = kernel[0].length;
int yk_length = kernel.length;
public ConvolutionFilter(double[][] kernel) {
this(null, kernel);
}
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, (stopY-startY), y+1));
for(int x=startX; x<stopX ;x++){
tmpData[y][x][0] = data[y][x][0]; // alpha
for(int yk=0; yk<yk_length ;yk++){
for(int xk=0; xk<xk_length ;xk++){
if(0 <= y-yk_length/2+yk && y-yk_length/2+yk < data.length &&
0 <= x-xk_length/2+xk && x-xk_length/2+xk < data[0].length){ // check that its not out of index
tmpData[y][x][1] += data[y-yk_length/2+yk][x-xk_length/2+xk][1] * kernel[yk][xk];
tmpData[y][x][2] += data[y-yk_length/2+yk][x-xk_length/2+xk][2] * kernel[yk][xk];
tmpData[y][x][3] += data[y-yk_length/2+yk][x-xk_length/2+xk][3] * kernel[yk][xk];
}
}
}
}
}
RAWImageUtil.clip(tmpData, startX, startY, stopX, stopY);
return tmpData;
}
/**
* Returns the kernel or null if it has not been generated yet.
*/
public double[][] getKernel(){
return kernel;
}
/**
* Should be overridden by a subclass
*
* @return an special generated kernel
*/
protected double[][] generateKernel(){
return null;
}
/**
* Applies an Convolution kernel to the specified image
*
* @param img is the image
* @param kernel is the kernel to apply to the image
*/
public ConvolutionFilter(BufferedImage img, double[][] kernel) {
super(img);
this.kernel = kernel;
}
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
if(kernel == null) this.kernel = generateKernel();
int[][][] tmpData = new int[data.length][data[0].length][4];
int xk_length = kernel[0].length;
int yk_length = kernel.length;
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, (stopY-startY), y+1));
for(int x=startX; x<stopX ;x++){
tmpData[y][x][0] = data[y][x][0]; // alpha
for(int yk=0; yk<yk_length ;yk++){
for(int xk=0; xk<xk_length ;xk++){
if(0 <= y-yk_length/2+yk && y-yk_length/2+yk < data.length &&
0 <= x-xk_length/2+xk && x-xk_length/2+xk < data[0].length){ // check that its not out of index
tmpData[y][x][1] += data[y-yk_length/2+yk][x-xk_length/2+xk][1] * kernel[yk][xk];
tmpData[y][x][2] += data[y-yk_length/2+yk][x-xk_length/2+xk][2] * kernel[yk][xk];
tmpData[y][x][3] += data[y-yk_length/2+yk][x-xk_length/2+xk][3] * kernel[yk][xk];
}
}
}
}
}
RAWImageUtil.clip(tmpData, startX, startY, stopX, stopY);
return tmpData;
}
/**
* Returns the kernel or null if it has not been generated yet.
*/
public double[][] getKernel(){
return kernel;
}
/**
* Should be overridden by a subclass
*
* @return an special generated kernel
*/
protected double[][] generateKernel(){
return null;
}
}

View file

@ -32,67 +32,67 @@ import java.awt.image.BufferedImage;
public class DitheringFilter extends ImageFilterProcessor{
// default palette is black and white
private int[][] palette = {
{255,0,0,0},
{255,255,255,255}
};
// default palette is black and white
private int[][] palette = {
{255,0,0,0},
{255,255,255,255}
};
/**
* Sets up a default DitheringEffect
*/
public DitheringFilter(BufferedImage img){
super(img);
}
/**
* Creates a Dithering Effect object
* @param img The image to apply the effect on
* @param palette The palette to use on the image
* int[colorCount][4]
* 0 -> Alpha data
* Red data
* Green data
* 4 -> Blue data
*/
public DitheringFilter(BufferedImage img, int[][] palette){
super(img);
this.palette = palette;
}
/**
* Sets up a default DitheringEffect
*/
public DitheringFilter(BufferedImage img){
super(img);
}
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int error, index;
int[] currentPixel;
int[][][] output = RAWImageUtil.copyArray(data);
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, stopY-startY-1, y));
for(int x=startX; x<stopX ;x++){
currentPixel = output[y][x];
index = findNearestColor(currentPixel, palette);
output[y][x] = palette[index];
/**
* Creates a Dithering Effect object
* @param img The image to apply the effect on
* @param palette The palette to use on the image
* int[colorCount][4]
* 0 -> Alpha data
* Red data
* Green data
* 4 -> Blue data
*/
public DitheringFilter(BufferedImage img, int[][] palette){
super(img);
this.palette = palette;
}
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int error, index;
int[] currentPixel;
int[][][] output = RAWImageUtil.copyArray(data);
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, stopY-startY-1, y));
for(int x=startX; x<stopX ;x++){
currentPixel = output[y][x];
index = findNearestColor(currentPixel, palette);
output[y][x] = palette[index];
for (int i = 1; i < 4; i++) {
error = currentPixel[i] - palette[index][i];
if (x + 1 < output[0].length) {
output[y+0][x+1][i] = RAWImageUtil.clip( output[y+0][x+1][i] + (error*7)/16 );
}
if (y + 1 < data.length) {
if (x - 1 > 0)
output[y+1][x-1][i] = RAWImageUtil.clip( output[y+1][x-1][i] + (error*3)/16 );
output[y+1][x+0][i] = RAWImageUtil.clip( output[y+1][x+0][i] + (error*5)/16 );
if (x + 1 < data[0].length)
output[y+1][x+1][i] = RAWImageUtil.clip( output[y+1][x+1][i] + (error*1)/16 );
}
}
}
}
return output;
}
for (int i = 1; i < 4; i++) {
error = currentPixel[i] - palette[index][i];
if (x + 1 < output[0].length) {
output[y+0][x+1][i] = RAWImageUtil.clip( output[y+0][x+1][i] + (error*7)/16 );
}
if (y + 1 < data.length) {
if (x - 1 > 0)
output[y+1][x-1][i] = RAWImageUtil.clip( output[y+1][x-1][i] + (error*3)/16 );
output[y+1][x+0][i] = RAWImageUtil.clip( output[y+1][x+0][i] + (error*5)/16 );
if (x + 1 < data[0].length)
output[y+1][x+1][i] = RAWImageUtil.clip( output[y+1][x+1][i] + (error*1)/16 );
}
}
}
}
return output;
}
private static int findNearestColor(int[] color, int[][] palette) {
int minDistanceSquared = 255*255 + 255*255 + 255*255 + 1;
int bestIndex = 0;

View file

@ -32,40 +32,40 @@ import java.awt.image.BufferedImage;
* @author Ziver
*/
public class GaussianBlurFilter extends ConvolutionFilter{
private int size;
private double sigma;
private int size;
private double sigma;
public GaussianBlurFilter(BufferedImage img) {
this(img, 5, 1.4);
}
public GaussianBlurFilter(BufferedImage img, int size, double sigma) {
super(img);
this.size = size;
this.sigma = sigma;
}
public GaussianBlurFilter(BufferedImage img) {
this(img, 5, 1.4);
}
protected double[][] generateKernel(){
return gaussianFunction(size, size, sigma);
}
/**
* Generates the kernel from the specified values
*/
public static double[][] gaussianFunction(int size_x, int size_y, double sigma){
double[][] kernel;
int center_x = size_x/2;
int center_y = size_y/2;
kernel = new double[size_y][size_x];
for(int y=0; y<size_y ;y++){
for(int x=0; x<size_x ;x++){
double tmp_x = (double)( (x-center_x)*(x-center_x) )/(2*sigma*sigma);
double tmp_y = (double)( (y-center_y)*(y-center_y) )/(2*sigma*sigma);
kernel[y][x] = 1.0/(2*Math.PI*sigma*sigma) * Math.exp( -(tmp_x + tmp_y) );
}
}
public GaussianBlurFilter(BufferedImage img, int size, double sigma) {
super(img);
this.size = size;
this.sigma = sigma;
}
return kernel;
}
protected double[][] generateKernel(){
return gaussianFunction(size, size, sigma);
}
/**
* Generates the kernel from the specified values
*/
public static double[][] gaussianFunction(int size_x, int size_y, double sigma){
double[][] kernel;
int center_x = size_x/2;
int center_y = size_y/2;
kernel = new double[size_y][size_x];
for(int y=0; y<size_y ;y++){
for(int x=0; x<size_x ;x++){
double tmp_x = (double)( (x-center_x)*(x-center_x) )/(2*sigma*sigma);
double tmp_y = (double)( (y-center_y)*(y-center_y) )/(2*sigma*sigma);
kernel[y][x] = 1.0/(2*Math.PI*sigma*sigma) * Math.exp( -(tmp_x + tmp_y) );
}
}
return kernel;
}
}

View file

@ -32,38 +32,38 @@ import java.awt.image.BufferedImage;
* @author Ziver
*/
public class MeanBlurFilter extends ConvolutionFilter{
private int windowSize;
private int windowSize;
/**
* Setup a default MedianFilter
*
* @param img is the image to process
*/
public MeanBlurFilter(BufferedImage img) {
this(img, 10);
}
/**
* Setup a default MedianFilter
*
* @param img is the image to process
*/
public MeanBlurFilter(BufferedImage img) {
this(img, 10);
}
/**
* Setup a default MedianFilter
*
* @param img is the image to process
* @param pixels is the size of the window
*/
public MeanBlurFilter(BufferedImage img, int pixels) {
super(img);
this.windowSize = pixels;
}
protected double[][] generateKernel(){
double[][] kernel = new double[windowSize][windowSize];
double mean = 1.0/(windowSize*windowSize);
for(int y=0; y<windowSize ;y++){
for(int x=0; x<windowSize ;x++){
kernel[y][x] = mean;
}
}
return kernel;
}
/**
* Setup a default MedianFilter
*
* @param img is the image to process
* @param pixels is the size of the window
*/
public MeanBlurFilter(BufferedImage img, int pixels) {
super(img);
this.windowSize = pixels;
}
protected double[][] generateKernel(){
double[][] kernel = new double[windowSize][windowSize];
double mean = 1.0/(windowSize*windowSize);
for(int y=0; y<windowSize ;y++){
for(int x=0; x<windowSize ;x++){
kernel[y][x] = mean;
}
}
return kernel;
}
}

View file

@ -37,42 +37,42 @@ import java.awt.image.BufferedImage;
* @author Ziver
*/
public class MedianFilter extends ImageFilterProcessor{
private int windowSize;
private boolean[] channels;
private int windowSize;
private boolean[] channels;
/**
* Setup a default MedianFilter
*
* @param img The image to process
*/
public MedianFilter(BufferedImage img) {
this(img, 10);
}
/**
* Setup a default MedianFilter
*
* @param img The image to process
*/
public MedianFilter(BufferedImage img) {
this(img, 10);
}
/**
* Setup a default MedianFilter
*
* @param img The image to process
* @param pixels The size of the window
*/
public MedianFilter(BufferedImage img, int pixels) {
this(img, pixels, new boolean[]{true,true,true,true});
}
/**
* Setup a default MedianFilter
*
* @param img The image to process
* @param pixels The size of the window
*/
public MedianFilter(BufferedImage img, int pixels) {
this(img, pixels, new boolean[]{true,true,true,true});
}
/**
* Setup a default MedianFilter
*
* @param img The image to process
* @param pixels The size of the window
* @param channels Is a 4 element array for witch channels to use the filter on
*/
public MedianFilter(BufferedImage img, int pixels, boolean[] channels) {
super(img);
this.windowSize = pixels;
this.channels = channels;
}
/**
* Setup a default MedianFilter
*
* @param img The image to process
* @param pixels The size of the window
* @param channels Is a 4 element array for witch channels to use the filter on
*/
public MedianFilter(BufferedImage img, int pixels, boolean[] channels) {
super(img);
this.windowSize = pixels;
this.channels = channels;
}
/*
/*
edgex := (window width / 2) rounded down
edgey := (window height / 2) rounded down
for x from edgex to image width - edgex:
@ -83,112 +83,112 @@ public class MedianFilter extends ImageFilterProcessor{
colorArray[fx][fy] := pixelvalue[x + fx - edgex][y + fy - edgey]
Sort colorArray[][];
pixelValue[x][y] := colorArray[window width / 2][window height / 2];
*/
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int[][][] tmpData = RAWImageUtil.copyArray(data);
*/
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
int[][][] tmpData = RAWImageUtil.copyArray(data);
int edgeX = windowSize / 2;
int edgeY = windowSize / 2;
int edgeX = windowSize / 2;
int edgeY = windowSize / 2;
int[][] tmpArray = new int[4][256*2];
int pixelCount = 0;
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, stopY-startY-1, y));
for(int x=startX; x<stopX ;x++){
int[][] tmpArray = new int[4][256*2];
int pixelCount = 0;
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, stopY-startY-1, y));
for(int x=startX; x<stopX ;x++){
pixelCount = 0;
for(int fy=0; fy<windowSize ;fy++){
for(int fx=0; fx<windowSize ;fx++){
if(y+fy-edgeY >= 0 && y+fy-edgeY < data.length && x+fx-edgeX >= 0 && x+fx-edgeX < data[0].length){
//colorArray[fx][fy] := pixelvalue[x + fx - edgex][y + fy - edgey]
if(channels[0]) tmpArray[0][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][0] ) ]++;
if(channels[1]) tmpArray[1][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][1] ) ]++;
if(channels[2]) tmpArray[2][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][2] ) ]++;
if(channels[3]) tmpArray[3][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][3] ) ]++;
pixelCount++;
}
}
}
pixelCount = 0;
for(int fy=0; fy<windowSize ;fy++){
for(int fx=0; fx<windowSize ;fx++){
if(y+fy-edgeY >= 0 && y+fy-edgeY < data.length && x+fx-edgeX >= 0 && x+fx-edgeX < data[0].length){
//colorArray[fx][fy] := pixelvalue[x + fx - edgex][y + fy - edgey]
if(channels[0]) tmpArray[0][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][0] ) ]++;
if(channels[1]) tmpArray[1][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][1] ) ]++;
if(channels[2]) tmpArray[2][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][2] ) ]++;
if(channels[3]) tmpArray[3][ getMedianIndex( tmpData[y + fy - edgeY][x + fx - edgeX][3] ) ]++;
pixelCount++;
}
}
}
if(channels[0]) tmpData[y][x][0] = findMedian(tmpArray[0], pixelCount/2);
if(channels[1]) tmpData[y][x][1] = findMedian(tmpArray[1], pixelCount/2);
if(channels[2]) tmpData[y][x][2] = findMedian(tmpArray[2], pixelCount/2);
if(channels[3]) tmpData[y][x][3] = findMedian(tmpArray[3], pixelCount/2);
}
}
return tmpData;
}
if(channels[0]) tmpData[y][x][0] = findMedian(tmpArray[0], pixelCount/2);
if(channels[1]) tmpData[y][x][1] = findMedian(tmpArray[1], pixelCount/2);
if(channels[2]) tmpData[y][x][2] = findMedian(tmpArray[2], pixelCount/2);
if(channels[3]) tmpData[y][x][3] = findMedian(tmpArray[3], pixelCount/2);
}
}
private int getMedianIndex(int i){
if(i < 0) return Math.abs(i);
else return i+256;
}
return tmpData;
}
private int findMedian(int[] median, int medianCount){
int sum = 0;
int ret = 0;
for(int i=0; i<median.length ;i++){
sum += median[i];
median[i] = 0;
if(sum >= medianCount && ret == 0){
ret = i-256;
}
}
private int getMedianIndex(int i){
if(i < 0) return Math.abs(i);
else return i+256;
}
return ret;
}
private int findMedian(int[] median, int medianCount){
int sum = 0;
int ret = 0;
for(int i=0; i<median.length ;i++){
sum += median[i];
median[i] = 0;
if(sum >= medianCount && ret == 0){
ret = i-256;
}
}
return ret;
}
class SortableARGB implements SortableDataList<Integer>{
private int[][][] data;
private int cols;
private int rows;
private int channel;
class SortableARGB implements SortableDataList<Integer>{
private int[][][] data;
private int cols;
private int rows;
private int channel;
public SortableARGB(int[][][] data, int cols, int rows, int channel){
this.data = data;
this.cols = cols;
this.rows = rows;
this.channel = channel;
}
public SortableARGB(int[][][] data, int cols, int rows, int channel){
this.data = data;
this.cols = cols;
this.rows = rows;
this.channel = channel;
}
public int compare(int a, int b) {
return compare(a, data[ getY(b) ][ getX(b) ][ channel ]);
}
public int compare(int a, int b) {
return compare(a, data[ getY(b) ][ getX(b) ][ channel ]);
}
public int compare(int a, Integer b) {
return ((Integer)data[ getY(a) ][ getX(a) ][ channel ]).compareTo(b);
}
public int compare(int a, Integer b) {
return ((Integer)data[ getY(a) ][ getX(a) ][ channel ]).compareTo(b);
}
public Integer get(int i) {
return data[ getY(i) ][ getX(i) ][ channel ];
}
public void set(int i, Integer o){
data[ getY(i) ][ getX(i) ][ channel ] = o;
}
public Integer get(int i) {
return data[ getY(i) ][ getX(i) ][ channel ];
}
public int size() {
return cols * rows;
}
public void set(int i, Integer o){
data[ getY(i) ][ getX(i) ][ channel ] = o;
}
public void swap(int a, int b) {
int tmp = data[ getY(a) ][ getX(a) ][ channel ];
data[ getY(a) ][ getX(a) ][ channel ] = data[ getY(b) ][ getX(b) ][ channel ];
data[ getY(b) ][ getX(b) ][ channel ] = tmp;
}
public int size() {
return cols * rows;
}
public void swap(int a, int b) {
int tmp = data[ getY(a) ][ getX(a) ][ channel ];
data[ getY(a) ][ getX(a) ][ channel ] = data[ getY(b) ][ getX(b) ][ channel ];
data[ getY(b) ][ getX(b) ][ channel ] = tmp;
}
private int getX(int a){
return a % cols;
}
private int getX(int a){
return a % cols;
}
private int getY(int a){
return a / cols;
}
private int getY(int a){
return a / cols;
}
}
}
}

View file

@ -30,58 +30,58 @@ import zutil.math.ZMath;
import java.awt.image.BufferedImage;
public class ResizeImage extends ImageFilterProcessor{
private int width;
private int height;
private int[][][] newData;
/**
* Will create a ResizeImage object and fix the height with the aspect
* of the width
*
* @param img The image to resize
* @param w The new width
*/
public ResizeImage(BufferedImage img, int w){
this(img, w, -1);
}
/**
* Will create a ResizeImage object
*
* @param img The image to resize
* @param w The new width if -1 then it will be scaled whit aspect of the hight
* @param h The new height if -1 then it will be scaled whit aspect of the width
*/
public ResizeImage(BufferedImage img, int w, int h){
super(img);
width = w;
height = h;
}
@Override
public int[][][] process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
if(width < 1){
height = (int)(((double)width/(stopX-startX))*(stopY-startY));
}
else if(height < 1){
width = (int)(((double)height/(stopY-startY))*(stopX-startY));
}
newData = new int[height][width][4];
double xScale = ((double)(stopX-startX)/width);
double yScale = ((double)(stopY-startY)/height);
for(int y=0; y<width ;y++){
setProgress(ZMath.percent(0, width-1, y));
for(int x=0; x<height ;x++){
newData[y][x][0] = data[(int)(y*yScale)][(int)(x*xScale)][0];
newData[y][x][1] = data[(int)(y*yScale)][(int)(x*xScale)][1];
newData[y][x][2] = data[(int)(y*yScale)][(int)(x*xScale)][2];
newData[y][x][3] = data[(int)(y*yScale)][(int)(x*xScale)][3];
}
}
return newData;
}
private int width;
private int height;
private int[][][] newData;
/**
* Will create a ResizeImage object and fix the height with the aspect
* of the width
*
* @param img The image to resize
* @param w The new width
*/
public ResizeImage(BufferedImage img, int w){
this(img, w, -1);
}
/**
* Will create a ResizeImage object
*
* @param img The image to resize
* @param w The new width if -1 then it will be scaled whit aspect of the hight
* @param h The new height if -1 then it will be scaled whit aspect of the width
*/
public ResizeImage(BufferedImage img, int w, int h){
super(img);
width = w;
height = h;
}
@Override
public int[][][] process(final int[][][] data, int startX, int startY, int stopX, int stopY) {
if(width < 1){
height = (int)(((double)width/(stopX-startX))*(stopY-startY));
}
else if(height < 1){
width = (int)(((double)height/(stopY-startY))*(stopX-startY));
}
newData = new int[height][width][4];
double xScale = ((double)(stopX-startX)/width);
double yScale = ((double)(stopY-startY)/height);
for(int y=0; y<width ;y++){
setProgress(ZMath.percent(0, width-1, y));
for(int x=0; x<height ;x++){
newData[y][x][0] = data[(int)(y*yScale)][(int)(x*xScale)][0];
newData[y][x][1] = data[(int)(y*yScale)][(int)(x*xScale)][1];
newData[y][x][2] = data[(int)(y*yScale)][(int)(x*xScale)][2];
newData[y][x][3] = data[(int)(y*yScale)][(int)(x*xScale)][3];
}
}
return newData;
}
}

View file

@ -36,53 +36,51 @@ import java.awt.image.BufferedImage;
* INFO: http://en.wikipedia.org/wiki/Sobel_operator
*/
public class SobelEdgeDetectionFilter extends ImageFilterProcessor{
private static final double[][] xG_kernel = new double[][]{
{+1, 0, -1},
{+2, 0, -2},
{+1, 0, -1}
};
private static final double[][] yG_kernel = new double[][]{
{+1, +2, +1},
{ 0, 0, 0},
{-1, -2, -1}
};
public SobelEdgeDetectionFilter(BufferedImage img) {
super(img);
}
private static final double[][] xG_kernel = new double[][]{
{+1, 0, -1},
{+2, 0, -2},
{+1, 0, -1}
};
private static final double[][] yG_kernel = new double[][]{
{+1, +2, +1},
{ 0, 0, 0},
{-1, -2, -1}
};
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
ConvolutionFilter conv = new ConvolutionFilter(xG_kernel);
int[][][] xG = conv.process(data, startX, startY, stopX, stopY);
setProgress(33);
conv = new ConvolutionFilter(yG_kernel);
int[][][] yG = conv.process(data, startX, startY, stopX, stopY);
setProgress(66);
int[][][] output = new int[data.length][data[0].length][4];
for(int y=startY; y<stopY ;y++){
setProgress(66+ZMath.percent(0, (stopY-startY), y+1)/100*34);
for(int x=startX; x<stopX ;x++){
output[y][x][0] = data[y][x][0];
output[y][x][1] = (int)Math.sqrt( xG[y][x][1]*xG[y][x][1] + yG[y][x][1]*yG[y][x][1] );
output[y][x][2] = (int)Math.sqrt( xG[y][x][2]*xG[y][x][2] + yG[y][x][2]*yG[y][x][2] );
output[y][x][3] = (int)Math.sqrt( xG[y][x][3]*xG[y][x][3] + yG[y][x][3]*yG[y][x][3] );
/*
output[y][x][1] = Math.abs( xG[y][x][1] ) + Math.abs(yG[y][x][1] );
output[y][x][2] = Math.abs( xG[y][x][2] ) + Math.abs(yG[y][x][2] );
output[y][x][3] = Math.abs( xG[y][x][3] ) + Math.abs(yG[y][x][3] );
*/
}
}
// gradient's direction:
// 0 = arctan( yG/xG )
return output;
}
public SobelEdgeDetectionFilter(BufferedImage img) {
super(img);
}
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
ConvolutionFilter conv = new ConvolutionFilter(xG_kernel);
int[][][] xG = conv.process(data, startX, startY, stopX, stopY);
setProgress(33);
conv = new ConvolutionFilter(yG_kernel);
int[][][] yG = conv.process(data, startX, startY, stopX, stopY);
setProgress(66);
int[][][] output = new int[data.length][data[0].length][4];
for(int y=startY; y<stopY ;y++){
setProgress(66+ZMath.percent(0, (stopY-startY), y+1)/100*34);
for(int x=startX; x<stopX ;x++){
output[y][x][0] = data[y][x][0];
output[y][x][1] = (int)Math.sqrt( xG[y][x][1]*xG[y][x][1] + yG[y][x][1]*yG[y][x][1] );
output[y][x][2] = (int)Math.sqrt( xG[y][x][2]*xG[y][x][2] + yG[y][x][2]*yG[y][x][2] );
output[y][x][3] = (int)Math.sqrt( xG[y][x][3]*xG[y][x][3] + yG[y][x][3]*yG[y][x][3] );
/*
output[y][x][1] = Math.abs( xG[y][x][1] ) + Math.abs(yG[y][x][1] );
output[y][x][2] = Math.abs( xG[y][x][2] ) + Math.abs(yG[y][x][2] );
output[y][x][3] = Math.abs( xG[y][x][3] ) + Math.abs(yG[y][x][3] );
*/
}
}
// gradient's direction:
// 0 = arctan( yG/xG )
return output;
}
}

View file

@ -31,69 +31,69 @@ import zutil.math.ZMath;
import java.awt.image.BufferedImage;
public class SpotLightFilter extends ImageFilterProcessor{
private int radius;
private int xPos;
private int yPos;
/**
* Sets up a default spotlight effect in
* the middle of the image
*/
public SpotLightFilter(BufferedImage img){
this(img, 100, -1, -1);
}
private int radius;
private int xPos;
private int yPos;
/**
* Sets up a custom spotlight
* @param r The radius of the spotlight in pixels
*/
public SpotLightFilter(BufferedImage img, int r){
this(img, r, -1, -1);
}
/**
* Sets up a custom spotlight
* @param r The radius of the spotlight in pixels
* @param x The x position of the spotlight, if -1 then it will be centered
* @param y The y position of the spotlight, if -1 then it will be centered
*/
public SpotLightFilter(BufferedImage img, int r, int x, int y){
super(img);
radius = r;
xPos = x;
yPos = y;
}
/**
* Sets up a default spotlight effect in
* the middle of the image
*/
public SpotLightFilter(BufferedImage img){
this(img, 100, -1, -1);
}
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
if(xPos < 0) xPos = data[0].length/2;
if(yPos < 0) yPos = data.length/2;
int[][][] output = new int[data.length][data[0].length][4];
double scale, dx, dy, distance;
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, (stopY-startY)-1, y));
for(int x=startX; x<stopX ;x++){
dx = x-xPos;
dy = y-yPos;
distance = Math.sqrt(dx*dx+dy*dy);
if(distance > radius){
scale = 0;
}
else{
scale = 1-(distance/radius);
}
output[y][x][0] = data[y][x][0];
output[y][x][1] = RAWImageUtil.clip((int)(scale * data[y][x][1]));
output[y][x][2] = RAWImageUtil.clip((int)(scale * data[y][x][2]));
output[y][x][3] = RAWImageUtil.clip((int)(scale * data[y][x][3]));
}
}
return output;
}
/**
* Sets up a custom spotlight
* @param r The radius of the spotlight in pixels
*/
public SpotLightFilter(BufferedImage img, int r){
this(img, r, -1, -1);
}
/**
* Sets up a custom spotlight
* @param r The radius of the spotlight in pixels
* @param x The x position of the spotlight, if -1 then it will be centered
* @param y The y position of the spotlight, if -1 then it will be centered
*/
public SpotLightFilter(BufferedImage img, int r, int x, int y){
super(img);
radius = r;
xPos = x;
yPos = y;
}
@Override
public int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY) {
if(xPos < 0) xPos = data[0].length/2;
if(yPos < 0) yPos = data.length/2;
int[][][] output = new int[data.length][data[0].length][4];
double scale, dx, dy, distance;
for(int y=startY; y<stopY ;y++){
setProgress(ZMath.percent(0, (stopY-startY)-1, y));
for(int x=startX; x<stopX ;x++){
dx = x-xPos;
dy = y-yPos;
distance = Math.sqrt(dx*dx+dy*dy);
if(distance > radius){
scale = 0;
}
else{
scale = 1-(distance/radius);
}
output[y][x][0] = data[y][x][0];
output[y][x][1] = RAWImageUtil.clip((int)(scale * data[y][x][1]));
output[y][x][2] = RAWImageUtil.clip((int)(scale * data[y][x][2]));
output[y][x][3] = RAWImageUtil.clip((int)(scale * data[y][x][3]));
}
}
return output;
}
}

View file

@ -33,23 +33,23 @@ import java.io.InputStream;
* until it gets to a boundary and will return -1 (end of stream).
* The stream will not return any data until the {@link #next()}
* method is called.
*
*
* @author Ziver
*
*/
public class BufferedBoundaryInputStream extends FilterInputStream{
/** The size of the buffer in bytes */
protected static final int DEFAULT_BUF_SIZE = 8192;
/** The size of the buffer in bytes */
protected static final int DEFAULT_BUF_SIZE = 8192;
/** The raw buffer */
/** The raw buffer */
private byte buffer[];
/** The current position in the buffer */
private int buf_pos = 0;
/** The end position of the buffer */
/** The end position of the buffer */
private int buf_end = 0;
/** Boundary position, 0< means no boundary found */
private int buf_bound_pos = -1;
/** The boundary (the delimiter) */
/** The boundary (the delimiter) */
private byte[] boundary;
/** The position in the buffer where user has marked, -1 if no mark is set **/
private int buf_mark = -1;
@ -57,77 +57,76 @@ public class BufferedBoundaryInputStream extends FilterInputStream{
private int buf_mark_limit = 0;
/**
* Creates a instance of this class with a default buffer size of 64K
*
* @param in is the InputStream that the buffer will use
*/
public BufferedBoundaryInputStream(InputStream in){
this(in, DEFAULT_BUF_SIZE);
}
/**
* Creates a instance of this class with a default buffer size of 64K
*
* @param in is the InputStream that the buffer will use
*/
public BufferedBoundaryInputStream(InputStream in){
this(in, DEFAULT_BUF_SIZE);
}
/**
* Creates a instance of this class
*
* @param in is the InputStream that the buffer will use
* @param buf_size speifies the buffer size
*/
public BufferedBoundaryInputStream(InputStream in, int buf_size){
super(in);
buffer = new byte[buf_size];
}
/**
* Creates a instance of this class
*
* @param in is the InputStream that the buffer will use
* @param buf_size speifies the buffer size
*/
public BufferedBoundaryInputStream(InputStream in, int buf_size){
super(in);
buffer = new byte[buf_size];
}
/**
/**
* @return the next byte from the stream or -1 if EOF or stream has encountered a boundary
*/
public int read() throws IOException{
*/
public int read() throws IOException{
if (fillBuffer() < 0)
return -1;
if(isOnBoundary())
return -1; // boundary
return buffer[buf_pos++];
}
return -1; // boundary
return buffer[buf_pos++];
}
/**
* Fills the given array with data from the buffer
*
* @param b is the array that will be filled
* @return the amount of bytes read or -1 if EOF or stream is on a boundary
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Reads a given length of bytes from the buffer
*
* @param b is the array that will be filled
* @param off is the offset in the array
* @param len is the amount to read
/**
* Fills the given array with data from the buffer
*
* @param b is the array that will be filled
* @return the amount of bytes read or -1 if EOF or stream is on a boundary
*/
public int read(byte b[], int off, int len) throws IOException {
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Reads a given length of bytes from the buffer
*
* @param b is the array that will be filled
* @param off is the offset in the array
* @param len is the amount to read
* @return the amount of bytes read or -1 if EOF or stream is on a boundary
*/
public int read(byte b[], int off, int len) throws IOException {
if (fillBuffer() < 0)
return -1; // EOF
if (isOnBoundary())
return -1; // boundary
return -1; // boundary
// The request is larger then the buffer size
int leftover = available();
if (len > leftover)
len = leftover;
// The request is larger then the buffer size
int leftover = available();
if (len > leftover)
len = leftover;
// the boundary is in the read range
if (buf_pos < buf_bound_pos && buf_bound_pos < buf_pos+len)
len = buf_bound_pos - buf_pos;
System.arraycopy(buffer, buf_pos, b, off, len);
buf_pos += len;
return len;
}
// the boundary is in the read range
if (buf_pos < buf_bound_pos && buf_bound_pos < buf_pos+len)
len = buf_bound_pos - buf_pos;
System.arraycopy(buffer, buf_pos, b, off, len);
buf_pos += len;
return len;
}
/**
@ -157,76 +156,76 @@ public class BufferedBoundaryInputStream extends FilterInputStream{
/**
* Skips over the closest boundary
*/
public void next() throws IOException {
// read data until we find the next boundary or get to the end of the stream
if (buf_bound_pos < 0) {
public void next() throws IOException {
// read data until we find the next boundary or get to the end of the stream
if (buf_bound_pos < 0) {
while (fillBuffer() >= 0 && buf_bound_pos < 0)
buf_pos = buf_end;
}
if (buf_bound_pos >= 0){ // is boundary in buffer?
buf_pos += boundary.length;
findNextBoundary();
}
}
if (buf_bound_pos >= 0){ // is boundary in buffer?
buf_pos += boundary.length;
findNextBoundary();
}
}
/**
* Skips a specific amounts of bytes in the buffer.
* Note that his method does not check for boundaries
/**
* Skips a specific amounts of bytes in the buffer.
* Note that his method does not check for boundaries
* and it will only skip in the local buffer.
*
*
* @param n the number of bytes to be skipped.
* @return the actual number of bytes skipped,
* 0 if it has reach the end of the buffer but does not mean end of stream.
*/
public long skip(long n) throws IOException {
int leftover = available();
if(n > leftover){
buf_pos = buf_end;
return leftover;
}
return buf_pos += n;
}
/**
* Sets the boundary for the stream
*/
public void setBoundary(String b){
this.boundary = b.getBytes();
findNextBoundary(); // redo the search with the new boundary
}
/**
* Sets the boundary for the stream
*/
public void setBoundary(byte[] b){
boundary = new byte[b.length];
System.arraycopy(b, 0, boundary, 0, b.length);
findNextBoundary(); // redo the search with the new boundary
}
*/
public long skip(long n) throws IOException {
int leftover = available();
if(n > leftover){
buf_pos = buf_end;
return leftover;
}
return buf_pos += n;
}
/**
* @return an estimate of the number of bytes that can be read (or skipped
* over) from this buffered input stream without blocking.
*/
public int available() throws IOException {
if (super.available() <= 0)
return buf_end - buf_pos; // return the whole stream as there are no more boundaries
/**
* Sets the boundary for the stream
*/
public void setBoundary(String b){
this.boundary = b.getBytes();
findNextBoundary(); // redo the search with the new boundary
}
/**
* Sets the boundary for the stream
*/
public void setBoundary(byte[] b){
boundary = new byte[b.length];
System.arraycopy(b, 0, boundary, 0, b.length);
findNextBoundary(); // redo the search with the new boundary
}
/**
* @return an estimate of the number of bytes that can be read (or skipped
* over) from this buffered input stream without blocking.
*/
public int available() throws IOException {
if (super.available() <= 0)
return buf_end - buf_pos; // return the whole stream as there are no more boundaries
else if (buf_end < boundary.length)
return 0; // we need a safety block in case boundary is split
return buf_end - boundary.length - buf_pos;
}
return 0; // we need a safety block in case boundary is split
return buf_end - boundary.length - buf_pos;
}
/**
* @return true for BufferedBoundaryInputStream
*/
public boolean markSupported(){
return true;
}
public boolean markSupported(){
return true;
}
/**
* See {@link InputStream#mark(int)} for details

View file

@ -36,221 +36,221 @@ import java.io.RandomAccessFile;
* @author Ziver
*/
public class BufferedRandomAccessFile extends RandomAccessFile{
// The size of the buffer in Byte
private int BUF_SIZE = 64*1024;
// The size of the buffer in Byte
private int BUF_SIZE = 64*1024;
// The Buffer
byte buffer[];
// The end of the buffer
int buf_end = 0;
// The position in the buffer
int buf_pos = 0;
// The real file pointer position where the buffer starts
long file_pos = 0;
// The Buffer
byte buffer[];
// The end of the buffer
int buf_end = 0;
// The position in the buffer
int buf_pos = 0;
// The real file pointer position where the buffer starts
long file_pos = 0;
/**
* Create a instance of this buffer
*
* @param filename is the file to read from
* @param mode as in {@link java.io.RandomAccessFile#RandomAccessFile(File file, String mode)}
*/
public BufferedRandomAccessFile(String filename, String mode) throws IOException{
this(new File(filename), mode);
}
/**
* Create a instance of this buffer
*
* @param file is the file to read from
* @param mode as in {@link java.io.RandomAccessFile#RandomAccessFile(File file, String mode)}
*/
public BufferedRandomAccessFile(File file, String mode) throws IOException{
super(file,mode);
invalidate();
buffer = new byte[BUF_SIZE];
}
/**
* Create a instance of this buffer
*
* @param filename is the file to read from
* @param mode as in {@link java.io.RandomAccessFile#RandomAccessFile(File file, String mode)}
* @param bufsize is the buffer size in bytes
* @throws IOException
*/
public BufferedRandomAccessFile(String filename, String mode, int bufsize) throws IOException{
this(new File(filename), mode, bufsize);
}
/**
* Create a instance of this buffer
*
* @param file is the file to read from
* @param mode as in {@link java.io.RandomAccessFile#RandomAccessFile(File file, String mode)}
* @param bufsize is the buffer size in bytes
* @throws IOException
*/
public BufferedRandomAccessFile(File file, String mode, int bufsize) throws IOException{
super(file,mode);
invalidate();
BUF_SIZE = bufsize;
buffer = new byte[BUF_SIZE];
}
/**
* Create a instance of this buffer
*
* @param filename is the file to read from
* @param mode as in {@link java.io.RandomAccessFile#RandomAccessFile(File file, String mode)}
*/
public BufferedRandomAccessFile(String filename, String mode) throws IOException{
this(new File(filename), mode);
}
/**
* Reads in data from the file to the buffer
*
* @return the buffer
* @throws IOException
*/
private int fillBuffer() throws IOException {
int n = super.read(buffer, 0, BUF_SIZE );
if(n >= 0) {
file_pos +=n;
buf_end = n;
buf_pos = 0;
}
return n;
}
/**
* Create a instance of this buffer
*
* @param file is the file to read from
* @param mode as in {@link java.io.RandomAccessFile#RandomAccessFile(File file, String mode)}
*/
public BufferedRandomAccessFile(File file, String mode) throws IOException{
super(file,mode);
invalidate();
buffer = new byte[BUF_SIZE];
}
/**
* Resets the buffer
*
* @throws IOException
*/
private void invalidate() throws IOException {
buf_end = 0;
buf_pos = 0;
file_pos = super.getFilePointer();
}
/**
* Create a instance of this buffer
*
* @param filename is the file to read from
* @param mode as in {@link java.io.RandomAccessFile#RandomAccessFile(File file, String mode)}
* @param bufsize is the buffer size in bytes
* @throws IOException
*/
public BufferedRandomAccessFile(String filename, String mode, int bufsize) throws IOException{
this(new File(filename), mode, bufsize);
}
/**
* @return the next byte in the buffer
*/
public final int read() throws IOException{
if(buf_pos >= buf_end) {
if(fillBuffer() < 0)
return -1;
}
if(buf_end == 0) {
return -1;
} else {
buf_pos++;
return buffer[buf_pos-1];
}
}
/**
* Fills the given array with data from the buffer
*
* @param b is the array that will be filled
* @return the amount of bytes read or -1 if eof
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Reads a given length of bytes from the buffer
*
* @param b is the array that will be filled
* @param off is the offset in the array
* @param len is the amount to read
* @return the amount of bytes read or -1 if eof
*/
public int read(byte b[], int off, int len) throws IOException {
if(buf_pos >= buf_end) {
if(fillBuffer() < 0)
return -1; // EOF
}
// Copy from buffer
int leftover = buf_end - buf_pos;
if(len <= leftover) {
System.arraycopy(buffer, buf_pos, b, off, len);
buf_pos += len;
return len;
}
System.arraycopy(buffer, buf_pos, b, off, leftover);
int n = super.read(b, off+leftover, len-leftover );
fillBuffer();
if( n >= 0 )
return leftover + n;
return leftover;
/*for(int i = 0; i < len; i++) {
int c = this.read();
if(c != -1)
b[off+i] = (byte)c;
else {
return i;
}
}
return len;*/
}
/**
* Create a instance of this buffer
*
* @param file is the file to read from
* @param mode as in {@link java.io.RandomAccessFile#RandomAccessFile(File file, String mode)}
* @param bufsize is the buffer size in bytes
* @throws IOException
*/
public BufferedRandomAccessFile(File file, String mode, int bufsize) throws IOException{
super(file,mode);
invalidate();
BUF_SIZE = bufsize;
buffer = new byte[BUF_SIZE];
}
/**
* @return the file pointer in the file
*/
public long getFilePointer() throws IOException{
long l = file_pos;
return (l - buf_end + buf_pos) ;
}
/**
* Changes the file pointer to another position
*
* @param pos The position to move the pointer to
*/
public void seek(long pos) throws IOException {
int n = (int)(file_pos - pos);
if(n >= 0 && n <= buf_end) {
buf_pos = buf_end - n;
} else {
super.seek(pos);
invalidate();
}
}
/**
* Reads in data from the file to the buffer
*
* @return the buffer
* @throws IOException
*/
private int fillBuffer() throws IOException {
int n = super.read(buffer, 0, BUF_SIZE );
if(n >= 0) {
file_pos +=n;
buf_end = n;
buf_pos = 0;
}
return n;
}
/**
* This method is a replacement for readLine()
*
* @return the next line in the file
*/
public final String readNextLine() throws IOException {
String str = null;
if(buf_end-buf_pos <= 0) {
if(fillBuffer() < 0) {
throw new IOException("Error filling buffer!");
}
}
int lineend = -1;
for(int i = buf_pos; i < buf_end; i++) {
if(buffer[i] == '\n') {
lineend = i;
break;
}
}
if(lineend < 0) {
StringBuffer input = new StringBuffer(256);
int c;
while (((c = read()) != -1) && (c != '\n')) {
input.append((char)c);
}
if ((c == -1) && (input.length() == 0)) {
return null;
}
return input.toString();
}
if(lineend > 0 && buffer[lineend-1] == '\r'){
str = new String(buffer, buf_pos, lineend - buf_pos -1);
}
else {
str = new String(buffer, buf_pos, lineend - buf_pos);
}
buf_pos = lineend +1;
return str;
}
/**
* Resets the buffer
*
* @throws IOException
*/
private void invalidate() throws IOException {
buf_end = 0;
buf_pos = 0;
file_pos = super.getFilePointer();
}
/**
* @return the next byte in the buffer
*/
public final int read() throws IOException{
if(buf_pos >= buf_end) {
if(fillBuffer() < 0)
return -1;
}
if(buf_end == 0) {
return -1;
} else {
buf_pos++;
return buffer[buf_pos-1];
}
}
/**
* Fills the given array with data from the buffer
*
* @param b is the array that will be filled
* @return the amount of bytes read or -1 if eof
*/
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
/**
* Reads a given length of bytes from the buffer
*
* @param b is the array that will be filled
* @param off is the offset in the array
* @param len is the amount to read
* @return the amount of bytes read or -1 if eof
*/
public int read(byte b[], int off, int len) throws IOException {
if(buf_pos >= buf_end) {
if(fillBuffer() < 0)
return -1; // EOF
}
// Copy from buffer
int leftover = buf_end - buf_pos;
if(len <= leftover) {
System.arraycopy(buffer, buf_pos, b, off, len);
buf_pos += len;
return len;
}
System.arraycopy(buffer, buf_pos, b, off, leftover);
int n = super.read(b, off+leftover, len-leftover );
fillBuffer();
if( n >= 0 )
return leftover + n;
return leftover;
/*for(int i = 0; i < len; i++) {
int c = this.read();
if(c != -1)
b[off+i] = (byte)c;
else {
return i;
}
}
return len;*/
}
/**
* @return the file pointer in the file
*/
public long getFilePointer() throws IOException{
long l = file_pos;
return (l - buf_end + buf_pos) ;
}
/**
* Changes the file pointer to another position
*
* @param pos The position to move the pointer to
*/
public void seek(long pos) throws IOException {
int n = (int)(file_pos - pos);
if(n >= 0 && n <= buf_end) {
buf_pos = buf_end - n;
} else {
super.seek(pos);
invalidate();
}
}
/**
* This method is a replacement for readLine()
*
* @return the next line in the file
*/
public final String readNextLine() throws IOException {
String str = null;
if(buf_end-buf_pos <= 0) {
if(fillBuffer() < 0) {
throw new IOException("Error filling buffer!");
}
}
int lineend = -1;
for(int i = buf_pos; i < buf_end; i++) {
if(buffer[i] == '\n') {
lineend = i;
break;
}
}
if(lineend < 0) {
StringBuffer input = new StringBuffer(256);
int c;
while (((c = read()) != -1) && (c != '\n')) {
input.append((char)c);
}
if ((c == -1) && (input.length() == 0)) {
return null;
}
return input.toString();
}
if(lineend > 0 && buffer[lineend-1] == '\r'){
str = new String(buffer, buf_pos, lineend - buf_pos -1);
}
else {
str = new String(buffer, buf_pos, lineend - buf_pos);
}
buf_pos = lineend +1;
return str;
}
}

View file

@ -29,137 +29,137 @@ import java.io.InputStream;
import java.util.ArrayList;
public class DynamicByteArrayStream extends InputStream{
/** The byte array container */
private ArrayList<byte[]> bytes;
/** Current virtual position of the stream */
private int globalPos;
/** Current virtual size of the stream */
private int globalSize;
/** Points the current byte array index */
private int globalArrayIndex;
/** Points to a local index in the current byte array */
private int localArrayOffset;
/** The byte array container */
private ArrayList<byte[]> bytes;
/** Current virtual position of the stream */
private int globalPos;
/** Current virtual size of the stream */
private int globalSize;
/** Points the current byte array index */
private int globalArrayIndex;
/** Points to a local index in the current byte array */
private int localArrayOffset;
/**
* Create a new instance of DynamicByteArrayStream
*/
public DynamicByteArrayStream(){
bytes = new ArrayList<byte[]>();
globalPos = 0;
globalSize = 0;
globalArrayIndex = 0;
localArrayOffset = 0;
}
/**
* Create a new instance of DynamicByteArrayStream
*/
public DynamicByteArrayStream(){
bytes = new ArrayList<byte[]>();
globalPos = 0;
globalSize = 0;
globalArrayIndex = 0;
localArrayOffset = 0;
}
/**
* Append an byte array to the stream
*
* @param b is the byte array to add.
*/
public synchronized void append(byte[] b){
bytes.add(b);
globalSize += b.length;
}
/**
* Append an byte array to the stream.
* NOTE: This function will copy data.
*
* @param b is the byte array to add
* @param offset is the offset in the byte array
* @param length is the amount of data to add
*/
public synchronized void append(byte[] b, int offset, int length){
byte[] new_b = new byte[length];
System.arraycopy(b, offset, new_b, 0, length);
bytes.add(new_b);
globalSize += length;
}
/**
* Append an byte array to the stream
*
* @param b is the byte array to add.
*/
public synchronized void append(byte[] b){
bytes.add(b);
globalSize += b.length;
}
@Override
public synchronized int read() throws IOException {
if(globalPos >= globalSize) return -1;
int ret = bytes.get(globalArrayIndex)[localArrayOffset] & 0xff;
globalPos++;
localArrayOffset++;
if(localArrayOffset >= bytes.get(globalArrayIndex).length){
globalArrayIndex++;
localArrayOffset = 0;
}
return ret;
}
/**
* Append an byte array to the stream.
* NOTE: This function will copy data.
*
* @param b is the byte array to add
* @param offset is the offset in the byte array
* @param length is the amount of data to add
*/
public synchronized void append(byte[] b, int offset, int length){
byte[] new_b = new byte[length];
System.arraycopy(b, offset, new_b, 0, length);
bytes.add(new_b);
globalSize += length;
}
public synchronized int read(byte b[], int off, int len) {
if(len <= 0) return 0;
if(globalPos >= globalSize) return -1;
@Override
public synchronized int read() throws IOException {
if(globalPos >= globalSize) return -1;
int ret = bytes.get(globalArrayIndex)[localArrayOffset] & 0xff;
globalPos++;
localArrayOffset++;
if(localArrayOffset >= bytes.get(globalArrayIndex).length){
globalArrayIndex++;
localArrayOffset = 0;
}
return ret;
}
public synchronized int read(byte b[], int off, int len) {
if(len <= 0) return 0;
if(globalPos >= globalSize) return -1;
int bytes_read=0;
if(globalPos+len >= globalSize) len = globalSize - globalPos;
while(bytes_read<len){
byte[] src = bytes.get(globalArrayIndex);
if(globalPos+len >= globalSize) len = globalSize - globalPos;
while(bytes_read<len){
byte[] src = bytes.get(globalArrayIndex);
// Read length is LONGER than local array
if(localArrayOffset +len-bytes_read > src.length){
int length = src.length- localArrayOffset;
System.arraycopy(src, localArrayOffset, b, off+bytes_read, length);
localArrayOffset = 0;
globalArrayIndex++;
bytes_read += length;
}
if(localArrayOffset +len-bytes_read > src.length){
int length = src.length- localArrayOffset;
System.arraycopy(src, localArrayOffset, b, off+bytes_read, length);
localArrayOffset = 0;
globalArrayIndex++;
bytes_read += length;
}
// Read length is SHORTER than local array
else{
int length = len-bytes_read;
System.arraycopy(src, localArrayOffset, b, off+bytes_read, length);
localArrayOffset += length;
bytes_read += length;
}
}
globalPos += len;
return bytes_read;
}
else{
int length = len-bytes_read;
System.arraycopy(src, localArrayOffset, b, off+bytes_read, length);
public synchronized int available() {
return globalSize - globalPos;
}
localArrayOffset += length;
bytes_read += length;
}
}
globalPos += len;
return bytes_read;
}
/**
* Clears this stream from the byte arrays
*/
public synchronized void clear(){
globalSize = 0;
reset();
bytes.clear();
}
public synchronized void reset() {
globalArrayIndex = 0;
localArrayOffset = 0;
globalPos = 0;
}
public synchronized int available() {
return globalSize - globalPos;
}
public void close() throws IOException {
clear();
}
/**
* @return all of the buffers content as a byte array.
*/
public byte[] getBytes(){
byte[] data = new byte[globalSize];
this.read(data, 0, globalSize);
return data;
}
/**
* WARNING: This function might return a malformed String.
*
* @return all the contents of the buffers as a String.
*/
public String toString(){
/**
* Clears this stream from the byte arrays
*/
public synchronized void clear(){
globalSize = 0;
reset();
bytes.clear();
}
public synchronized void reset() {
globalArrayIndex = 0;
localArrayOffset = 0;
globalPos = 0;
}
public void close() throws IOException {
clear();
}
/**
* @return all of the buffers content as a byte array.
*/
public byte[] getBytes(){
byte[] data = new byte[globalSize];
this.read(data, 0, globalSize);
return data;
}
/**
* WARNING: This function might return a malformed String.
*
* @return all the contents of the buffers as a String.
*/
public String toString(){
return new String( this.getBytes() );
}
}
}

View file

@ -45,24 +45,24 @@ public class IOUtil {
return readContent(stream, false);
}
/**
* Reads and returns all the content of a stream.
*
* @param stream
/**
* Reads and returns all the content of a stream.
*
* @param stream
* @param close true if the stream should be closed at the end
* @return a byte array with the stream contents
*/
public static byte[] readContent(InputStream stream, boolean close) throws IOException{
* @return a byte array with the stream contents
*/
public static byte[] readContent(InputStream stream, boolean close) throws IOException{
DynamicByteArrayStream dyn_buff = new DynamicByteArrayStream();
byte[] buff = new byte[8192];
int len = 0;
while((len = stream.read(buff)) != -1){
dyn_buff.append(buff, 0, len);
}
while((len = stream.read(buff)) != -1){
dyn_buff.append(buff, 0, len);
}
if (close) stream.close();
return dyn_buff.getBytes();
}
if (close) stream.close();
return dyn_buff.getBytes();
}
/**
* Reads and returns all the content of a stream as a String.

View file

@ -36,27 +36,27 @@ import java.io.InputStream;
* @author Ziver
*/
public class InputStreamCloser extends InputStream{
private Closeable[] c;
private InputStream in;
public InputStreamCloser(InputStream in, Closeable... c){
this.c = c;
this.in = in;
}
private Closeable[] c;
private InputStream in;
public void close() throws IOException {
in.close();
for (Closeable stream : c)
stream.close();
}
public InputStreamCloser(InputStream in, Closeable... c){
this.c = c;
this.in = in;
}
// Mirror functions
public int read() throws IOException { return in.read(); }
public int read(byte b[]) throws IOException { return in.read(b); }
public int read(byte b[], int off, int len) throws IOException { return in.read(b, off, len); }
public long skip(long n) throws IOException { return in.skip(n); }
public int available() throws IOException { return in.available(); }
public synchronized void mark(int readlimit) { in.mark(readlimit); }
public synchronized void reset() throws IOException { in.reset(); }
public boolean markSupported() { return in.markSupported(); }
public void close() throws IOException {
in.close();
for (Closeable stream : c)
stream.close();
}
// Mirror functions
public int read() throws IOException { return in.read(); }
public int read(byte b[]) throws IOException { return in.read(b); }
public int read(byte b[], int off, int len) throws IOException { return in.read(b, off, len); }
public long skip(long n) throws IOException { return in.skip(n); }
public int available() throws IOException { return in.available(); }
public synchronized void mark(int readlimit) { in.mark(readlimit); }
public synchronized void reset() throws IOException { in.reset(); }
public boolean markSupported() { return in.markSupported(); }
}

View file

@ -41,154 +41,154 @@ import java.util.Map;
* this class can print strings to multiple PrintStreams
*/
public class MultiPrintStream extends PrintStream {
//the print streams that will print
private ArrayList<PrintStream> streams;
//a instance of this class
public static MultiPrintStream out = new MultiPrintStream();
//the print streams that will print
private ArrayList<PrintStream> streams;
//a instance of this class
public static MultiPrintStream out = new MultiPrintStream();
public MultiPrintStream(){
super(new PrintStream(System.out));
streams = new ArrayList<PrintStream>();
streams.add(new PrintStream(System.out));
}
public MultiPrintStream(){
super(new PrintStream(System.out));
streams = new ArrayList<PrintStream>();
streams.add(new PrintStream(System.out));
}
/**
* This constructor makes a simple PrintStream that prints to the console and to a file
* @param file is the file name to output to
*/
public MultiPrintStream(String file){
super(new PrintStream(System.out));
try {
streams = new ArrayList<PrintStream>();
streams.add(new PrintStream(System.out));
streams.add(new PrintStream(new File(file)));
} catch (FileNotFoundException e) {
System.out.println("Error when declaring PrintStream!!");
e.printStackTrace();
}
}
/**
* This constructor makes a simple PrintStream that prints to the console and to a file
* @param file is the file name to output to
*/
public MultiPrintStream(String file){
super(new PrintStream(System.out));
try {
streams = new ArrayList<PrintStream>();
streams.add(new PrintStream(System.out));
streams.add(new PrintStream(new File(file)));
} catch (FileNotFoundException e) {
System.out.println("Error when declaring PrintStream!!");
e.printStackTrace();
}
}
/**
* This constructor takes a array of PrintStreams to be used
* @param streams is a array of the streams that will be used
*/
public MultiPrintStream(PrintStream[] streams){
super(streams[0]);
this.streams = new ArrayList<PrintStream>();
for(int i=0; i<streams.length ;i++){
this.streams.add(streams[i]);
}
}
/**
* This constructor takes a array of PrintStreams to be used
* @param streams is a array of the streams that will be used
*/
public MultiPrintStream(PrintStream[] streams){
super(streams[0]);
this.streams = new ArrayList<PrintStream>();
for(int i=0; i<streams.length ;i++){
this.streams.add(streams[i]);
}
}
/**
* This constructor takes a array of PrintStreams to be used
* @param instanceStream is a array of the streams that will be used
*/
public static void makeInstance(MultiPrintStream instanceStream){
out = instanceStream;
}
/**
* This constructor takes a array of PrintStreams to be used
* @param instanceStream is a array of the streams that will be used
*/
public static void makeInstance(MultiPrintStream instanceStream){
out = instanceStream;
}
/**
* Adds a PrintStream to the list of streams
* @param p is the PrintStream to add
*/
public void addPrintStream(PrintStream p){
streams.add(p);
}
/**
* Adds a PrintStream to the list of streams
* @param p is the PrintStream to add
*/
public void addPrintStream(PrintStream p){
streams.add(p);
}
/**
* Remove a PrintStream from the list
* @param p is the PrintStream to remove
*/
public void removePrintStream(PrintStream p){
streams.remove(p);
}
/**
* Remove a PrintStream from the list
* @param p is the PrintStream to remove
*/
public void removePrintStream(PrintStream p){
streams.remove(p);
}
/**
* Remove a PrintStream from the list
* @param p is the index of the PrintStream to remove
*/
public void removePrintStream(int p){
streams.remove(p);
}
/**
* Remove a PrintStream from the list
* @param p is the index of the PrintStream to remove
*/
public void removePrintStream(int p){
streams.remove(p);
}
/**
* writes to all the PrintStreams
*/
public void write(int b) {
for(int i=0; i<streams.size() ;i++)
streams.get(i).write(b);
}
/**
* writes to all the PrintStreams
*/
public void write(byte buf[], int off, int len){
for(int i=0; i<streams.size() ;i++)
streams.get(i).write(buf, off, len);
}
/**
* Prints with a new line to all the PrintStreams
*/
public void println(String s){
for(int i=0; i<streams.size() ;i++)
streams.get(i).println(s);
}
/**
* writes to all the PrintStreams
*/
public void write(int b) {
for(int i=0; i<streams.size() ;i++)
streams.get(i).write(b);
}
/**
* Prints to all the PrintStreams
*/
public void print(String s){
for(int i=0; i<streams.size() ;i++)
streams.get(i).print(s);
}
/**
* writes to all the PrintStreams
*/
public void write(byte buf[], int off, int len){
for(int i=0; i<streams.size() ;i++)
streams.get(i).write(buf, off, len);
}
public void println(){ println("");}
public void println(boolean x){ println(String.valueOf(x));}
public void println(char x){ println(String.valueOf(x));}
public void println(char[] x){ println(new String(x));}
public void println(double x){ println(String.valueOf(x));}
public void println(float x){ println(String.valueOf(x));}
public void println(int x){ println(String.valueOf(x));}
public void println(long x){ println(String.valueOf(x));}
public void println(Object x){ println(String.valueOf(x));}
/**
* Prints with a new line to all the PrintStreams
*/
public void println(String s){
for(int i=0; i<streams.size() ;i++)
streams.get(i).println(s);
}
public void print(boolean x){ print(String.valueOf(x));}
public void print(char x){ print(String.valueOf(x));}
public void print(char[] x){ print(new String(x));}
public void print(double x){ print(String.valueOf(x));}
public void print(float x){ print(String.valueOf(x));}
public void print(int x){ print(String.valueOf(x));}
public void print(long x){ print(String.valueOf(x));}
public void print(Object x){ print(String.valueOf(x));}
/**
* Prints to all the PrintStreams
*/
public void print(String s){
for(int i=0; i<streams.size() ;i++)
streams.get(i).print(s);
}
public void println(){ println("");}
public void println(boolean x){ println(String.valueOf(x));}
public void println(char x){ println(String.valueOf(x));}
public void println(char[] x){ println(new String(x));}
public void println(double x){ println(String.valueOf(x));}
public void println(float x){ println(String.valueOf(x));}
public void println(int x){ println(String.valueOf(x));}
public void println(long x){ println(String.valueOf(x));}
public void println(Object x){ println(String.valueOf(x));}
public void print(boolean x){ print(String.valueOf(x));}
public void print(char x){ print(String.valueOf(x));}
public void print(char[] x){ print(new String(x));}
public void print(double x){ print(String.valueOf(x));}
public void print(float x){ print(String.valueOf(x));}
public void print(int x){ print(String.valueOf(x));}
public void print(long x){ print(String.valueOf(x));}
public void print(Object x){ print(String.valueOf(x));}
public boolean checkError(){
for(int i=0; i<streams.size() ;i++)
if(streams.get(i).checkError())
return true;
return false;
}
public boolean checkError(){
for(int i=0; i<streams.size() ;i++)
if(streams.get(i).checkError())
return true;
return false;
}
/**
* closes all the PrintStreams
*/
public void close(){
for(int i=0; i<streams.size() ;i++)
streams.get(i).close();
}
/**
* closes all the PrintStreams
*/
public void close(){
for(int i=0; i<streams.size() ;i++)
streams.get(i).close();
}
/**
* Same as {@link #dump(Object, int)} but prints to this OutputStream.
*
* @param o is the Object to dump
*/
public void dump(Object o){
println(dumpToString( o, 1));
}
/**
* Same as {@link #dump(Object, int)} but prints to this OutputStream.
*
* @param o is the Object to dump
*/
public void dump(Object o){
println(dumpToString( o, 1));
}
/**
* Same as {@link #dump(Object, int)} but prints to this OutputStream.
@ -200,15 +200,15 @@ public class MultiPrintStream extends PrintStream {
println(dumpToString( o, depth));
}
/**
/**
* Same as {@link #dump(Object, int)}
*
* @param o is the Object to dump
* @return a String with all the printed data
*/
public static String dumpToString(Object o) {
return dumpToString(o, 1);
}
* @param o is the Object to dump
* @return a String with all the printed data
*/
public static String dumpToString(Object o) {
return dumpToString(o, 1);
}
/**
* Dumps the content of:
@ -225,157 +225,157 @@ public class MultiPrintStream extends PrintStream {
public static String dumpToString(Object o, int depth) {
return dumpToString(o, "", depth);
}
/**
* See {@link #dumpToString(Object)}
*
* @param o is the Object to dump
* @param head is the string that will be put in front of every line
* @param depth sets the object dump depth, the object recursion depth
* @return A String with all the printed data
*/
private static String dumpToString(Object o , String head, int depth) {
if(o == null)
return "NULL";
StringBuffer buffer = new StringBuffer();
Class<?> oClass = o.getClass();
buffer.append( oClass.getName() );
String nextHead = head + "\t";
// Prints out Arrays
if ( oClass.isArray() ) {
buffer.append( "[" );
for ( int i=0; i<Array.getLength(o) ;i++ ) {
Object value = Array.get(o,i);
buffer.append("\n");
buffer.append(nextHead);
buffer.append( (dumbCapable(value, depth-1) ?
/**
* See {@link #dumpToString(Object)}
*
* @param o is the Object to dump
* @param head is the string that will be put in front of every line
* @param depth sets the object dump depth, the object recursion depth
* @return A String with all the printed data
*/
private static String dumpToString(Object o , String head, int depth) {
if(o == null)
return "NULL";
StringBuffer buffer = new StringBuffer();
Class<?> oClass = o.getClass();
buffer.append( oClass.getName() );
String nextHead = head + "\t";
// Prints out Arrays
if ( oClass.isArray() ) {
buffer.append( "[" );
for ( int i=0; i<Array.getLength(o) ;i++ ) {
Object value = Array.get(o,i);
buffer.append("\n");
buffer.append(nextHead);
buffer.append( (dumbCapable(value, depth-1) ?
dumpToString(value, nextHead, depth-1) : value) );
if ( i+1<Array.getLength(o) )
buffer.append( "," );
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "]" );
}
// Prints out a list
else if(o instanceof Collection){
Iterator<?> it = ((Collection<?>)o).iterator();
buffer.append( "[" );
while(it.hasNext()){
Object value = it.next();
buffer.append("\n");
buffer.append(nextHead);
buffer.append( (dumbCapable(value, depth-1) ?
if ( i+1<Array.getLength(o) )
buffer.append( "," );
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "]" );
}
// Prints out a list
else if(o instanceof Collection){
Iterator<?> it = ((Collection<?>)o).iterator();
buffer.append( "[" );
while(it.hasNext()){
Object value = it.next();
buffer.append("\n");
buffer.append(nextHead);
buffer.append( (dumbCapable(value, depth-1) ?
dumpToString(value, nextHead, depth-1) : value) );
if(it.hasNext())
buffer.append( "," );
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "]" );
}
// Prints out a Map
else if(o instanceof Map){
Iterator<?> it = ((Map<?,?>)o).keySet().iterator();
buffer.append( "{" );
while(it.hasNext()){
Object key = it.next();
Object value = ((Map<?,?>)o).get(key);
buffer.append("\n");
buffer.append(nextHead);
buffer.append( key );
buffer.append( "=>" );
buffer.append( (dumbCapable(value, depth-1) ?
if(it.hasNext())
buffer.append( "," );
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "]" );
}
// Prints out a Map
else if(o instanceof Map){
Iterator<?> it = ((Map<?,?>)o).keySet().iterator();
buffer.append( "{" );
while(it.hasNext()){
Object key = it.next();
Object value = ((Map<?,?>)o).get(key);
buffer.append("\n");
buffer.append(nextHead);
buffer.append( key );
buffer.append( "=>" );
buffer.append( (dumbCapable(value, depth-1) ?
dumpToString(value, nextHead, depth-1) : value) );
if(it.hasNext())
buffer.append( "," );
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "}" );
}
// Prints out data from InputStream
else if(o instanceof InputStream){
buffer.append( " =>{\n" );
try {
InputStream in = (InputStream)o;
int tmp;
while((tmp = in.read()) != -1){
buffer.append(nextHead);
buffer.append( (char)tmp );
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "}" );
}
// Prints out data from InputStream
else if(o instanceof Reader){
buffer.append( " =>{\n" );
try {
Reader in = (Reader)o;
int tmp;
while((tmp = in.read()) != -1){
buffer.append(nextHead);
buffer.append( (char)tmp );
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "}" );
}
// Prints out Object properties
else{
buffer.append( "{" );
while ( oClass != null ) {
Field[] fields = oClass.getDeclaredFields();
for ( int i=0; i<fields.length; i++ ) {
if(it.hasNext())
buffer.append( "," );
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "}" );
}
// Prints out data from InputStream
else if(o instanceof InputStream){
buffer.append( " =>{\n" );
try {
InputStream in = (InputStream)o;
int tmp;
while((tmp = in.read()) != -1){
buffer.append(nextHead);
buffer.append( (char)tmp );
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "}" );
}
// Prints out data from InputStream
else if(o instanceof Reader){
buffer.append( " =>{\n" );
try {
Reader in = (Reader)o;
int tmp;
while((tmp = in.read()) != -1){
buffer.append(nextHead);
buffer.append( (char)tmp );
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "}" );
}
// Prints out Object properties
else{
buffer.append( "{" );
while ( oClass != null ) {
Field[] fields = oClass.getDeclaredFields();
for ( int i=0; i<fields.length; i++ ) {
if (Modifier.isFinal(fields[i].getModifiers())) // Skip constants
continue;
fields[i].setAccessible( true );
buffer.append("\n");
buffer.append(nextHead);
//buffer.append( fields[i].getType().getSimpleName() );
//buffer.append( " " );
buffer.append( fields[i].getName() );
buffer.append( " = " );
try {
Object value = fields[i].get(o);
if (value != null) {
buffer.append( (dumbCapable(value, depth-1) ?
fields[i].setAccessible( true );
buffer.append("\n");
buffer.append(nextHead);
//buffer.append( fields[i].getType().getSimpleName() );
//buffer.append( " " );
buffer.append( fields[i].getName() );
buffer.append( " = " );
try {
Object value = fields[i].get(o);
if (value != null) {
buffer.append( (dumbCapable(value, depth-1) ?
dumpToString(value, nextHead, depth-1) : value) );
}
} catch ( IllegalAccessException e ) {}
if ( i+1<fields.length )
buffer.append( "," );
}
oClass = oClass.getSuperclass();
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "}" );
}
}
} catch ( IllegalAccessException e ) {}
if ( i+1<fields.length )
buffer.append( "," );
}
oClass = oClass.getSuperclass();
}
buffer.append( "\n" );
buffer.append(head);
buffer.append( "}" );
}
return buffer.toString();
}
return buffer.toString();
}
/**
* An helper function for the dump function.
*/
private static boolean dumbCapable(Object o, int depth){
/**
* An helper function for the dump function.
*/
private static boolean dumbCapable(Object o, int depth){
if (depth <= 0)
return false;
if (o == null)
if (o == null)
return false;
if (ClassUtil.isPrimitive(o.getClass()) || ClassUtil.isWrapper(o.getClass()))
return false;
return true;
}
return true;
}
}

View file

@ -34,30 +34,30 @@ import java.nio.charset.StandardCharsets;
*
*/
public class StringInputStream extends InputStream{
// The buffer
protected StringBuilder buffer;
/**
* Creates an new instance of this class
*/
public StringInputStream(){
clear();
}
public StringInputStream(String data) {
clear();
add(data);
}
// The buffer
protected StringBuilder buffer;
/**
* Returns an estimate of the number of bytes
* that can be read (or skipped over) from this
* input stream without blocking by the next
* invocation of a method for this input stream.
*/
public int available(){
return buffer.length();
}
/**
* Creates an new instance of this class
*/
public StringInputStream(){
clear();
}
public StringInputStream(String data) {
clear();
add(data);
}
/**
* Returns an estimate of the number of bytes
* that can be read (or skipped over) from this
* input stream without blocking by the next
* invocation of a method for this input stream.
*/
public int available(){
return buffer.length();
}
/**
@ -65,36 +65,36 @@ public class StringInputStream extends InputStream{
*/
public int read(){
if(buffer.length() == 0)
return -1;
return -1;
int ret = buffer.charAt( 0 );
buffer.deleteCharAt( 0 );
return ret;
int ret = buffer.charAt( 0 );
buffer.deleteCharAt( 0 );
return ret;
}
/**
* Reads some number of bytes from the input stream
* and stores them into the buffer array b.
*/
public int read(byte[] b){
return read( b, 0, b.length );
return read( b, 0, b.length );
}
/**
* Reads up to len bytes of data from the input stream
* into an array of bytes.
*/
public int read(byte[] b, int off, int len){
if(buffer.length() == 0)
return -1;
if(buffer.length() == 0)
return -1;
if( buffer.length() < len ){
len = buffer.length();
}
byte[] btmp = buffer.substring(0, len).getBytes(StandardCharsets.ISO_8859_1);
System.arraycopy(btmp, 0, b, off, len);
buffer.delete(0, len);
return len;
if( buffer.length() < len ){
len = buffer.length();
}
byte[] btmp = buffer.substring(0, len).getBytes(StandardCharsets.ISO_8859_1);
System.arraycopy(btmp, 0, b, off, len);
buffer.delete(0, len);
return len;
}
@ -105,39 +105,39 @@ public class StringInputStream extends InputStream{
* @param n is the amount characters to skip
*/
public long skip(long n){
if( buffer.length() < n ){
int len = buffer.length();
buffer.delete(0, len);
return len;
}
else{
buffer.delete(0, (int) n);
return n;
}
if( buffer.length() < n ){
int len = buffer.length();
buffer.delete(0, len);
return len;
}
else{
buffer.delete(0, (int) n);
return n;
}
}
/**
* Tests if this input stream supports the mark and
* reset methods.
*/
public boolean markSupported(){
return false;
}
public boolean markSupported(){
return false;
}
/**
* Closes this input stream and releases any system
* resources associated with the stream.
*/
public void close(){
clear();
}
public void clear(){
buffer = new StringBuilder();
}
public void add( String data ){
buffer.append( data );
}
public void close(){
clear();
}
public void clear(){
buffer = new StringBuilder();
}
public void add( String data ){
buffer.append( data );
}
}

View file

@ -32,11 +32,11 @@ import java.io.File;
* @author Ziver
*/
public interface FileChangeListener{
/**
* This method is called when there is a change in a file
*
* @param file The file that has changed
*/
public void fileChangedEvent(File file);
/**
* This method is called when there is a change in a file
*
* @param file The file that has changed
*/
public void fileChangedEvent(File file);
}

View file

@ -35,67 +35,67 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class FileSearcher implements Iterable<FileSearcher.FileSearchItem>{
// Constants
private static final List<String> compressedFileExtensions = Arrays.asList(new String[]{
"jar", "zip"
});
// Constants
private static final List<String> compressedFileExtensions = Arrays.asList(new String[]{
"jar", "zip"
});
// Constructor params
private File root;
// Constructor params
private File root;
// Search parameters
private String fileName = null;
private String extension = null;
private boolean recursive = false;
//private int depth;
private boolean searchFiles = true;
// Search parameters
private String fileName = null;
private String extension = null;
private boolean recursive = false;
//private int depth;
private boolean searchFiles = true;
private boolean searchFolders = true;
private boolean searchCompressedFiles = false;
private boolean searchCompressedFiles = false;
public FileSearcher(File root){
this.root = root;
}
public FileSearcher(File root){
this.root = root;
}
/**
* @param file Sets the exact file name to search for (includes extension)
*/
public void setFileName(String file){
fileName = file;
}
/**
* Sets the file extensions to search for (should not include . at the beginning)
*/
public void setExtension(String ext){
extension = ext;
}
/**
* Defines if the search should go into sub-folders
*/
public void setRecursive(boolean recursive){
this.recursive = recursive;
}
/**
* Sets how deep into folders the search should go
* (Recursion needs to be enabled for this attribute to be used)
*/
//public void setDepth(int depth){
// this.depth = depth;
//}
/**
* Sets if the searcher should match to files.
/**
* @param file Sets the exact file name to search for (includes extension)
*/
public void setFileName(String file){
fileName = file;
}
/**
* Sets the file extensions to search for (should not include . at the beginning)
*/
public void setExtension(String ext){
extension = ext;
}
/**
* Defines if the search should go into sub-folders
*/
public void setRecursive(boolean recursive){
this.recursive = recursive;
}
/**
* Sets how deep into folders the search should go
* (Recursion needs to be enabled for this attribute to be used)
*/
//public void setDepth(int depth){
// this.depth = depth;
//}
/**
* Sets if the searcher should match to files.
*/
public void searchFiles(boolean searchFiles){
this.searchFiles = searchFiles;
}
/**
* Sets if the searcher should match to folders.
*/
public void searchFiles(boolean searchFiles){
this.searchFiles = searchFiles;
}
/**
* Sets if the searcher should match to folders.
*/
public void searchFolders(boolean searchFolders){
this.searchFolders = searchFolders;
}
@ -103,85 +103,85 @@ public class FileSearcher implements Iterable<FileSearcher.FileSearchItem>{
* Sets if the searcher should go into compressed files.
*/
public void searchCompressedFiles(boolean searchCompressedFiles){
this.searchCompressedFiles = searchCompressedFiles;
}
this.searchCompressedFiles = searchCompressedFiles;
}
@Override
public Iterator<FileSearchItem> iterator() {
return new FileSearchIterator();
}
@Override
public Iterator<FileSearchItem> iterator() {
return new FileSearchIterator();
}
protected class FileSearchIterator implements Iterator<FileSearchItem>{
private ArrayList<FileSearchItem> fileList;
private int index;
private FileSearchItem nextItem;
protected class FileSearchIterator implements Iterator<FileSearchItem>{
private ArrayList<FileSearchItem> fileList;
private int index;
private FileSearchItem nextItem;
public FileSearchIterator(){
fileList = new ArrayList<FileSearchItem>();
index = 0;
public FileSearchIterator(){
fileList = new ArrayList<FileSearchItem>();
index = 0;
addFiles(new FileSearchFileItem(root), root.list());
next();
}
addFiles(new FileSearchFileItem(root), root.list());
next();
}
@Override
public boolean hasNext() {
return nextItem != null;
}
@Override
public boolean hasNext() {
return nextItem != null;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public FileSearchItem next() {
// Temporarily save the current file
FileSearchItem ret = nextItem;
@Override
public FileSearchItem next() {
// Temporarily save the current file
FileSearchItem ret = nextItem;
// Find the next file
for(; index <fileList.size(); index++){
FileSearchItem file = fileList.get(index);
//#### FOLDERS
if(recursive && file.isDirectory()){
addFiles(file, file.listFiles());
if(searchFolders) {
// Find the next file
for(; index <fileList.size(); index++){
FileSearchItem file = fileList.get(index);
//#### FOLDERS
if(recursive && file.isDirectory()){
addFiles(file, file.listFiles());
if(searchFolders) {
if(fileName == null) // Match all folders
break;
else if(file.getName().equalsIgnoreCase(fileName))
break;
}
}
//#### COMPRESSED FILES
else if(searchCompressedFiles && file.isFile() &&
compressedFileExtensions.contains(
FileUtil.getFileExtension(file.getName()).toLowerCase())){
try {
ZipFile zipFile = new ZipFile(file.getPath());
Enumeration<? extends ZipEntry> e = zipFile.entries();
while(e.hasMoreElements()){
ZipEntry entry = e.nextElement();
fileList.add(new FileSearchZipItem(file.getPath(), entry));
}
zipFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//#### REGULAR FILES
else if(searchFiles && file.isFile()){
}
//#### COMPRESSED FILES
else if(searchCompressedFiles && file.isFile() &&
compressedFileExtensions.contains(
FileUtil.getFileExtension(file.getName()).toLowerCase())){
try {
ZipFile zipFile = new ZipFile(file.getPath());
Enumeration<? extends ZipEntry> e = zipFile.entries();
while(e.hasMoreElements()){
ZipEntry entry = e.nextElement();
fileList.add(new FileSearchZipItem(file.getPath(), entry));
}
zipFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//#### REGULAR FILES
else if(searchFiles && file.isFile()){
if(extension == null && fileName == null) // Should we match all files
break;
else if(extension != null &&
FileUtil.getFileExtension(file.getName()).equalsIgnoreCase(extension))
break;
else if(fileName != null &&
break;
else if(fileName != null &&
file.getName().equalsIgnoreCase(fileName))
break;
}
}
break;
}
}
if(index <fileList.size()) {
nextItem = fileList.get(index);
@ -190,84 +190,84 @@ public class FileSearcher implements Iterable<FileSearcher.FileSearchItem>{
else
nextItem = null;
return ret;
}
return ret;
}
private void addFiles(FileSearchItem root, String[] list){
if(root instanceof FileSearchFileItem) {
for (String file : list) {
fileList.add(new FileSearchFileItem(
new File(((FileSearchFileItem)root).file, file)));
}
}
}
private void addFiles(FileSearchItem root, String[] list){
if(root instanceof FileSearchFileItem) {
for (String file : list) {
fileList.add(new FileSearchFileItem(
new File(((FileSearchFileItem)root).file, file)));
}
}
}
}
}
public interface FileSearchItem{
/** @return a file or folder name **/
public String getName();
/** @return a path to the file or folder, in case of a compressed file the path to the package will be returned **/
public String getPath();
public interface FileSearchItem{
/** @return a file or folder name **/
public String getName();
/** @return a path to the file or folder, in case of a compressed file the path to the package will be returned **/
public String getPath();
public boolean isCompressed();
public boolean isFile();
public boolean isDirectory();
public boolean isCompressed();
public boolean isFile();
public boolean isDirectory();
/** @return an InputStream if this is a file otherwise null **/
public InputStream getInputStream() throws IOException;
/** @return an String array with all files if this is a folder otherwise null **/
public String[] listFiles();
}
/** @return an InputStream if this is a file otherwise null **/
public InputStream getInputStream() throws IOException;
/** @return an String array with all files if this is a folder otherwise null **/
public String[] listFiles();
}
protected static class FileSearchFileItem implements FileSearchItem{
private File file;
protected static class FileSearchFileItem implements FileSearchItem{
private File file;
protected FileSearchFileItem(File file){
this.file = file;
}
protected FileSearchFileItem(File file){
this.file = file;
}
public String getName() { return file.getName(); }
public String getPath() { return file.getAbsolutePath(); }
public String getName() { return file.getName(); }
public String getPath() { return file.getAbsolutePath(); }
public boolean isCompressed() { return false; }
public boolean isFile() { return file.isFile(); }
public boolean isDirectory() { return file.isDirectory(); }
public boolean isCompressed() { return false; }
public boolean isFile() { return file.isFile(); }
public boolean isDirectory() { return file.isDirectory(); }
public InputStream getInputStream() throws IOException { return new FileInputStream(file); }
public String[] listFiles() { return file.list(); }
public InputStream getInputStream() throws IOException { return new FileInputStream(file); }
public String[] listFiles() { return file.list(); }
public File getFile() { return file; }
public File getFile() { return file; }
}
}
protected static class FileSearchZipItem implements FileSearchItem{
private String zipFile;
private ZipEntry entry;
protected static class FileSearchZipItem implements FileSearchItem{
private String zipFile;
private ZipEntry entry;
private String fileName;
protected FileSearchZipItem(String file, ZipEntry entry){
this.zipFile = file;
this.entry = entry;
protected FileSearchZipItem(String file, ZipEntry entry){
this.zipFile = file;
this.entry = entry;
this.fileName = new File(entry.getName()).getName();
}
}
public String getName() { return fileName; }
public String getPath() { return "zip://"+zipFile+":"+entry.getName(); }
public String getName() { return fileName; }
public String getPath() { return "zip://"+zipFile+":"+entry.getName(); }
public boolean isCompressed() { return true; }
public boolean isFile() { return !entry.isDirectory(); }
public boolean isDirectory() { return entry.isDirectory(); }
public boolean isCompressed() { return true; }
public boolean isFile() { return !entry.isDirectory(); }
public boolean isDirectory() { return entry.isDirectory(); }
public InputStream getInputStream() throws IOException {
ZipFile zip = new ZipFile(zipFile);
return new InputStreamCloser(zip.getInputStream(entry), zip);
}
public String[] listFiles() { return null; }
public InputStream getInputStream() throws IOException {
ZipFile zip = new ZipFile(zipFile);
return new InputStreamCloser(zip.getInputStream(entry), zip);
}
public String[] listFiles() { return null; }
}
}
}

View file

@ -39,53 +39,53 @@ import java.util.TimerTask;
*
*/
public class FileWatcher extends TimerTask{
private FileChangeListener listener;
private long lastChanged;
private File file;
/**
* Creates a watcher for the given file whit the check
* interval of 1 second
*
* @param file is the file to check
* @throws FileNotFoundException
*/
public FileWatcher(File file) throws FileNotFoundException{
this(file, 1000);
}
/**
* Creates a watcher for the given file whit the given
* check interval
*
* @param file is the file
* @param intervall is the interval
* @throws FileNotFoundException
*/
public FileWatcher(File file, int intervall) throws FileNotFoundException{
if(file==null || !file.exists())
throw new FileNotFoundException("File not found: "+file);
this.file = file;
lastChanged = file.lastModified();
Timer t = new Timer(true);
t.schedule(this, 0, intervall);
}
public void setListener(FileChangeListener listener){
this.listener = listener;
}
private FileChangeListener listener;
private long lastChanged;
private File file;
@Override
public void run() {
if (lastChanged != file.lastModified()) {
lastChanged = file.lastModified();
if(listener != null){
listener.fileChangedEvent(file);
}
else{
MultiPrintStream.out.println("File Changed: "+file);
}
}
}
/**
* Creates a watcher for the given file whit the check
* interval of 1 second
*
* @param file is the file to check
* @throws FileNotFoundException
*/
public FileWatcher(File file) throws FileNotFoundException{
this(file, 1000);
}
/**
* Creates a watcher for the given file whit the given
* check interval
*
* @param file is the file
* @param intervall is the interval
* @throws FileNotFoundException
*/
public FileWatcher(File file, int intervall) throws FileNotFoundException{
if(file==null || !file.exists())
throw new FileNotFoundException("File not found: "+file);
this.file = file;
lastChanged = file.lastModified();
Timer t = new Timer(true);
t.schedule(this, 0, intervall);
}
public void setListener(FileChangeListener listener){
this.listener = listener;
}
@Override
public void run() {
if (lastChanged != file.lastModified()) {
lastChanged = file.lastModified();
if(listener != null){
listener.fileChangedEvent(file);
}
else{
MultiPrintStream.out.println("File Changed: "+file);
}
}
}
}

View file

@ -36,126 +36,126 @@ import zutil.parser.DataNode.DataType;
* uploaded file.
*/
public class FileUploadListener implements ProgressListener{
public static enum Status{
Initializing,
Uploading,
Processing,
Done,
Error
}
private String id;
private volatile Status status;
private volatile String filename;
private volatile String message;
private volatile long bytes = 0l;
private volatile long length = 0l;
private volatile int item = 0;
private volatile long time;
// Speed
private volatile int speed;
private volatile long speedRead;
private volatile long speedTime;
public FileUploadListener(){
id = ""+(int)(Math.random()*Integer.MAX_VALUE);
status = Status.Initializing;
filename = "";
message = "";
}
public void update(long pBytesRead, long pContentLength, int pItems) {
if(pContentLength < 0) this.length = pBytesRead;
else this.length = pContentLength;
this.bytes = pBytesRead;
this.item = pItems;
// Calculate Speed
if(speedTime == 0 || speedTime+1000 < System.currentTimeMillis() || pBytesRead == pContentLength){
speedTime = System.currentTimeMillis();
speed = (int)(pBytesRead-speedRead);
speedRead = pBytesRead;
}
//try{Thread.sleep(10);}catch(Exception e){}
public static enum Status{
Initializing,
Uploading,
Processing,
Done,
Error
}
// Set Status
status = Status.Uploading;
time = System.currentTimeMillis();
}
protected void setFileName(String filename){
this.filename = filename;
}
protected void setStatus(Status status){
this.status = status;
time = System.currentTimeMillis();
}
protected void setMessage(String msg){
this.message = msg;
}
public String getID(){
return id;
}
public String getFilename() {
return filename;
}
public long getBytesRead() {
return bytes;
}
private String id;
private volatile Status status;
private volatile String filename;
private volatile String message;
private volatile long bytes = 0l;
private volatile long length = 0l;
private volatile int item = 0;
private volatile long time;
public long getContentLength() {
return length;
}
// Speed
private volatile int speed;
private volatile long speedRead;
private volatile long speedTime;
public long getItem() {
return item;
}
public Status getStatus(){
return status;
}
protected long getTime(){
return time;
}
protected String getMessage(){
return message;
}
/**
* @return bytes per second
*/
public int getSpeed(){
return speed;
}
public FileUploadListener(){
id = ""+(int)(Math.random()*Integer.MAX_VALUE);
status = Status.Initializing;
filename = "";
message = "";
}
/**
* Calculate the percent complete
*/
public int getPercentComplete(){
if(length == 0)
return 0;
return (int)((100 * bytes) / length);
}
public void update(long pBytesRead, long pContentLength, int pItems) {
if(pContentLength < 0) this.length = pBytesRead;
else this.length = pContentLength;
this.bytes = pBytesRead;
this.item = pItems;
public DataNode getJSON() {
DataNode node = new DataNode( DataType.Map );
node.set("id", id);
node.set("status", status.toString());
node.set("message", message.replaceAll("\"", "\\\"") );
node.set("filename", filename);
node.set("percent", getPercentComplete());
node.set("uploaded", StringUtil.formatByteSizeToString(bytes));
node.set("total", StringUtil.formatByteSizeToString(length));
node.set("speed", StringUtil.formatByteSizeToString(speed)+"/s");
return node;
}
// Calculate Speed
if(speedTime == 0 || speedTime+1000 < System.currentTimeMillis() || pBytesRead == pContentLength){
speedTime = System.currentTimeMillis();
speed = (int)(pBytesRead-speedRead);
speedRead = pBytesRead;
}
//try{Thread.sleep(10);}catch(Exception e){}
// Set Status
status = Status.Uploading;
time = System.currentTimeMillis();
}
protected void setFileName(String filename){
this.filename = filename;
}
protected void setStatus(Status status){
this.status = status;
time = System.currentTimeMillis();
}
protected void setMessage(String msg){
this.message = msg;
}
public String getID(){
return id;
}
public String getFilename() {
return filename;
}
public long getBytesRead() {
return bytes;
}
public long getContentLength() {
return length;
}
public long getItem() {
return item;
}
public Status getStatus(){
return status;
}
protected long getTime(){
return time;
}
protected String getMessage(){
return message;
}
/**
* @return bytes per second
*/
public int getSpeed(){
return speed;
}
/**
* Calculate the percent complete
*/
public int getPercentComplete(){
if(length == 0)
return 0;
return (int)((100 * bytes) / length);
}
public DataNode getJSON() {
DataNode node = new DataNode( DataType.Map );
node.set("id", id);
node.set("status", status.toString());
node.set("message", message.replaceAll("\"", "\\\"") );
node.set("filename", filename);
node.set("percent", getPercentComplete());
node.set("uploaded", StringUtil.formatByteSizeToString(bytes));
node.set("total", StringUtil.formatByteSizeToString(length));
node.set("speed", StringUtil.formatByteSizeToString(speed)+"/s");
return node;
}
}

View file

@ -36,138 +36,138 @@ 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("yyyy-MM-dd HH:mm:ss.SSS");
/** 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();
/** 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("yyyy-MM-dd HH:mm:ss.SSS");
/** 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 prefix = new StringBuilder();
@Override
public String format(LogRecord record) {
StringBuilder prefix = new StringBuilder();
if( timeStamp ){
date.setTime( record.getMillis() );
prefix.append(dateFormatter.format(date));
prefix.append(' ');
}
if( timeStamp ){
date.setTime( record.getMillis() );
prefix.append(dateFormatter.format(date));
prefix.append(' ');
}
switch( record.getLevel().intValue() ){
case /* SEVERE */ 1000: prefix.append("[SEVERE] "); break;
case /* WARNING */ 900 : prefix.append("[WARNING]"); break;
case /* INFO */ 800 : prefix.append("[INFO] "); break;
case /* CONFIG */ 700 : prefix.append("[CONFIG] "); break;
case /* FINE */ 500 : prefix.append("[FINE] "); break;
case /* FINER */ 400 : prefix.append("[FINER] "); break;
case /* FINEST */ 300 : prefix.append("[FINEST] "); break;
}
prefix.append(' ');
switch( record.getLevel().intValue() ){
case /* SEVERE */ 1000: prefix.append("[SEVERE] "); break;
case /* WARNING */ 900 : prefix.append("[WARNING]"); break;
case /* INFO */ 800 : prefix.append("[INFO] "); break;
case /* CONFIG */ 700 : prefix.append("[CONFIG] "); break;
case /* FINE */ 500 : prefix.append("[FINE] "); break;
case /* FINER */ 400 : prefix.append("[FINER] "); break;
case /* FINEST */ 300 : prefix.append("[FINEST] "); break;
}
prefix.append(' ');
if( className ){
prefix.append(paddClassName(record.getSourceClassName()));
}
if(methodName){
prefix.append(record.getSourceMethodName());
}
prefix.append(": ");
if( className ){
prefix.append(paddClassName(record.getSourceClassName()));
}
if(methodName){
prefix.append(record.getSourceMethodName());
}
prefix.append(": ");
StringBuilder ret = new StringBuilder();
if( record.getMessage() != null ){
String[] array = splitter.split( record.getMessage() );
for( int i=0; i<array.length ;++i ){
if( i!=0 )
ret.append( '\n' );
if( prefix.length() > 0 )
ret.append( prefix );
ret.append( array[i] );
}
ret.append( '\n' );
}
StringBuilder ret = new StringBuilder();
if( record.getMessage() != null ){
String[] array = splitter.split( record.getMessage() );
for( int i=0; i<array.length ;++i ){
if( i!=0 )
ret.append( '\n' );
if( prefix.length() > 0 )
ret.append( prefix );
ret.append( array[i] );
}
ret.append( '\n' );
}
if( record.getThrown() != null ){
StringOutputStream out = new StringOutputStream();
record.getThrown().printStackTrace(new PrintStream(out));
String[] array = splitter.split( out.toString() );
for( int i=0; i<array.length ;++i ){
if( i!=0 )
ret.append( '\n' );
if( prefix.length() > 0 )
ret.append( prefix );
ret.append( array[i] );
}
ret.append( '\n' );
}
return ret.toString();
}
if( record.getThrown() != null ){
StringOutputStream out = new StringOutputStream();
record.getThrown().printStackTrace(new PrintStream(out));
String[] array = splitter.split( out.toString() );
for( int i=0; i<array.length ;++i ){
if( i!=0 )
ret.append( '\n' );
if( prefix.length() > 0 )
ret.append( prefix );
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;
}
/**
* 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);
}
/**
* 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 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;
}
/**
* 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 cStr = padd_cache.get(source);
if (cStr == null || cStr.length() != max_class_name) {
cStr = source.substring(source.lastIndexOf('.') + 1); // Remove packages
if (cStr.lastIndexOf('$') >= 0) { // extract subclass name
String subClass = cStr.substring(cStr.lastIndexOf('$') + 1);
/**
* @return the Class name
*/
private String paddClassName(String source){
String cStr = padd_cache.get(source);
if (cStr == null || cStr.length() != max_class_name) {
cStr = source.substring(source.lastIndexOf('.') + 1); // Remove packages
if (cStr.lastIndexOf('$') >= 0) { // extract subclass name
String subClass = cStr.substring(cStr.lastIndexOf('$') + 1);
if (!Pattern.matches("\\d+", subClass)) // Don'n substring for anonymous classes
cStr = subClass;
}
}
if (cStr.length() > max_class_name)
max_class_name = cStr.length();
if (cStr.length() > max_class_name)
max_class_name = cStr.length();
cStr += StringUtil.getSpaces(max_class_name - cStr.length());
padd_cache.put(source, cStr);
}
return cStr;
}
cStr += StringUtil.getSpaces(max_class_name - cStr.length());
padd_cache.put(source, cStr);
}
return cStr;
}
}

View file

@ -37,95 +37,95 @@ import java.util.logging.*;
* @author Ziver
*/
public class LogUtil {
private static final Logger logger = Logger.getLogger( LogUtil.class.getName() );
private static final Logger logger = Logger.getLogger( LogUtil.class.getName() );
private LogUtil(){}
private LogUtil(){}
/**
* @return a new Logger for the calling class
*/
public static Logger getLogger(){
return Logger.getLogger(ClassUtil.getCallingClass(LogUtil.class));
}
/**
* @return a new Logger for the calling class
*/
public static Logger getLogger(){
return Logger.getLogger(ClassUtil.getCallingClass(LogUtil.class));
}
/**
* Sets the log formatter to all root Handlers
*
* @param f is the formatter class
*/
public static void setGlobalFormatter(Formatter f){
Logger root = Logger.getLogger("");
for (Handler handler : root.getHandlers()) {
handler.setFormatter(f);
}
}
/**
* Adds the log formatter to all handlers in the namespace
*
* @param f is the formatter class
*/
public static void setFormatter(String name, Formatter f){
Logger root = Logger.getLogger(name);
for (Handler handler : root.getHandlers()) {
handler.setFormatter(f);
}
}
/**
* Sets the log formatter to all root Handlers
*
* @param f is the formatter class
*/
public static void setGlobalFormatter(Formatter f){
Logger root = Logger.getLogger("");
for (Handler handler : root.getHandlers()) {
handler.setFormatter(f);
}
}
/**
* Sets the global log level
*/
public static void setGlobalLevel(Level level){
setLevel("", level);
}
/**
* Adds the log formatter to all handlers in the namespace
*
* @param f is the formatter class
*/
public static void setFormatter(String name, Formatter f){
Logger root = Logger.getLogger(name);
for (Handler handler : root.getHandlers()) {
handler.setFormatter(f);
}
}
/**
* Adds a Handler to the root namespace
*/
public static void addGlobalHandler(Handler handler){
Logger root = Logger.getLogger("");
root.addHandler(handler);
}
/**
* Sets the log level for a specified class
*/
public static void setLevel(Class<?> c, Level level){
setLevel(c.getName(), level);
}
/**
* Sets the global log level
*/
public static void setGlobalLevel(Level level){
setLevel("", level);
}
/**
* Sets the log level for a specified logger
*/
public static void setLevel(String name, Level level){
logger.fine("Changing log level of \""+name+"\" to \""+level.getLocalizedName()+"\"");
Logger newLogger = Logger.getLogger(name);
newLogger.setLevel(level);
// Check if the logger has a handler
if( newLogger.getHandlers().length > 0 ){
// Set the level on the handlers if its level is higher
for (Handler handler : newLogger.getHandlers()) {
if(handler.getLevel().intValue() > level.intValue())
/**
* Adds a Handler to the root namespace
*/
public static void addGlobalHandler(Handler handler){
Logger root = Logger.getLogger("");
root.addHandler(handler);
}
/**
* Sets the log level for a specified class
*/
public static void setLevel(Class<?> c, Level level){
setLevel(c.getName(), level);
}
/**
* Sets the log level for a specified logger
*/
public static void setLevel(String name, Level level){
logger.fine("Changing log level of \""+name+"\" to \""+level.getLocalizedName()+"\"");
Logger newLogger = Logger.getLogger(name);
newLogger.setLevel(level);
// Check if the logger has a handler
if( newLogger.getHandlers().length > 0 ){
// Set the level on the handlers if its level is higher
for (Handler handler : newLogger.getHandlers()) {
if(handler.getLevel().intValue() > level.intValue())
handler.setLevel(level);
}
}
}
}
}
}
public static boolean isLoggable(Class clazz, Level level){
return Logger.getLogger(clazz.getName()).isLoggable(level);
}
public static boolean isLoggable(Class clazz, Level level){
return Logger.getLogger(clazz.getName()).isLoggable(level);
}
public static void readConfiguration(String file){
try{
File confFile = FileUtil.find(file);
if (confFile != null) {
FileInputStream in = new FileInputStream(confFile);
LogManager.getLogManager().readConfiguration(in);
in.close();
}
else
logger.warning("Unable to find logging configuration file: "+file);
File confFile = FileUtil.find(file);
if (confFile != null) {
FileInputStream in = new FileInputStream(confFile);
LogManager.getLogManager().readConfiguration(in);
in.close();
}
else
logger.warning("Unable to find logging configuration file: "+file);
} catch (Exception e){
logger.log(Level.SEVERE, "Unable to load logging configuration: "+file, e);
}

View file

@ -37,55 +37,55 @@ import java.util.logging.Logger;
public class NetLogClient extends Thread{
private static final Logger logger = LogUtil.getLogger();
private ConcurrentLinkedQueue<NetLogListener> listeners;
private Socket s;
private ObjectOutputStream out;
private static final Logger logger = LogUtil.getLogger();
public NetLogClient(String host, int port) throws UnknownHostException, IOException{
s = new Socket(host, port);
out = new ObjectOutputStream(s.getOutputStream());
listeners = new ConcurrentLinkedQueue<NetLogListener>();
this.start();
}
private ConcurrentLinkedQueue<NetLogListener> listeners;
private Socket s;
private ObjectOutputStream out;
public void addListener(NetLogListener listener){
logger.info("Registring new NetLogListener: "+listener.getClass().getName());
listeners.add( listener );
}
public NetLogClient(String host, int port) throws UnknownHostException, IOException{
s = new Socket(host, port);
out = new ObjectOutputStream(s.getOutputStream());
listeners = new ConcurrentLinkedQueue<NetLogListener>();
this.start();
}
public void run(){
try{
ObjectInputStream in = new ObjectInputStream(s.getInputStream());
while( true ){
Object o = in.readObject();
public void addListener(NetLogListener listener){
logger.info("Registring new NetLogListener: "+listener.getClass().getName());
listeners.add( listener );
}
for( NetLogListener listener : listeners ){
if( o instanceof NetLogMessage )
listener.handleLogMessage((NetLogMessage)o);
else if( o instanceof NetLogExceptionMessage )
listener.handleExceptionMessage((NetLogExceptionMessage)o);
else if( o instanceof NetLogStatusMessage )
listener.handleStatusMessage((NetLogStatusMessage)o);
else
logger.warning("Received unknown message: "+o.getClass().getName());
}
}
} catch( Exception e ){
logger.log(Level.SEVERE, null, e);
close();
}
}
public void run(){
try{
ObjectInputStream in = new ObjectInputStream(s.getInputStream());
while( true ){
Object o = in.readObject();
for( NetLogListener listener : listeners ){
if( o instanceof NetLogMessage )
listener.handleLogMessage((NetLogMessage)o);
else if( o instanceof NetLogExceptionMessage )
listener.handleExceptionMessage((NetLogExceptionMessage)o);
else if( o instanceof NetLogStatusMessage )
listener.handleStatusMessage((NetLogStatusMessage)o);
else
logger.warning("Received unknown message: "+o.getClass().getName());
}
}
} catch( Exception e ){
logger.log(Level.SEVERE, null, e);
close();
}
}
public void close(){
try{
this.interrupt();
s.close();
} catch (Exception e){
logger.log(Level.SEVERE, "Unable to close Client Socket.", e);
}
}
public void close(){
try{
this.interrupt();
s.close();
} catch (Exception e){
logger.log(Level.SEVERE, "Unable to close Client Socket.", e);
}
}
}

View file

@ -29,77 +29,77 @@ import zutil.net.nio.message.Message;
import java.util.logging.LogRecord;
public class NetLogExceptionMessage implements Message {
private static final long serialVersionUID = 1L;
private int count;
private String name;
private String message;
private String stackTrace;
NetLogExceptionMessage(String name, String message, String stackTrace){
this.count = 1;
this.name = name;
this.message = message;
this.stackTrace = stackTrace;
}
private static final long serialVersionUID = 1L;
public NetLogExceptionMessage(LogRecord record) {
Throwable exception = record.getThrown();
this.count = 1;
this.name = exception.getClass().getName();
this.message = exception.getMessage();
this.stackTrace = "";
for(int i=0; i<exception.getStackTrace().length; i++){
this.stackTrace += exception.getStackTrace()[i].toString();
}
}
private int count;
private String name;
private String message;
private String stackTrace;
NetLogExceptionMessage(String name, String message, String stackTrace){
this.count = 1;
this.name = name;
this.message = message;
this.stackTrace = stackTrace;
}
public NetLogExceptionMessage(LogRecord record) {
Throwable exception = record.getThrown();
this.count = 1;
this.name = exception.getClass().getName();
this.message = exception.getMessage();
this.stackTrace = "";
for(int i=0; i<exception.getStackTrace().length; i++){
this.stackTrace += exception.getStackTrace()[i].toString();
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((message == null) ? 0 : message.hashCode());
result = prime * result
+ ((stackTrace == null) ? 0 : stackTrace.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
NetLogExceptionMessage other = (NetLogExceptionMessage) obj;
if (name.equals(other.name) && message.equals(other.message) &&
stackTrace.equals(other.stackTrace)) {
return true;
}
return false;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((message == null) ? 0 : message.hashCode());
result = prime * result
+ ((stackTrace == null) ? 0 : stackTrace.hashCode());
return result;
}
public void addCount(int add){
count += add;
}
public int getCount() {
return count;
}
public String getName() {
return name;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
public String getMessage() {
return message;
}
NetLogExceptionMessage other = (NetLogExceptionMessage) obj;
if (name.equals(other.name) && message.equals(other.message) &&
stackTrace.equals(other.stackTrace)) {
return true;
}
return false;
}
public String getStackTrace() {
return stackTrace;
}
public void addCount(int add){
count += add;
}
public int getCount() {
return count;
}
public String getName() {
return name;
}
public String getMessage() {
return message;
}
public String getStackTrace() {
return stackTrace;
}
}

View file

@ -38,14 +38,14 @@ import javafx.stage.Stage;
import java.io.IOException;
public class NetLogGuiClient extends Application{
public static final String VERSION = "0.1";
// UI elements
@FXML
private TabPane tabPane;
public static final String VERSION = "0.1";
public static void main(String[] args) {
// UI elements
@FXML
private TabPane tabPane;
public static void main(String[] args) {
Application.launch(NetLogGuiClient.class, args);
}
@ -57,40 +57,40 @@ public class NetLogGuiClient extends Application{
stage.setScene(new Scene(root));
stage.show();
}
// Menu Actions
// Menu Actions
@FXML
protected void handleConnectAction(ActionEvent event) {
try{
tabPane.getTabs().add(new NetLoggerClientTab("koc.se", 8080));
}catch(Exception e){
e.printStackTrace();
}
protected void handleConnectAction(ActionEvent event) {
try{
tabPane.getTabs().add(new NetLoggerClientTab("koc.se", 8080));
}catch(Exception e){
e.printStackTrace();
}
}
@FXML
protected void handleExitAction(ActionEvent event) {
System.exit(0);
@FXML
protected void handleExitAction(ActionEvent event) {
System.exit(0);
}
@FXML
protected void handleAboutAction(ActionEvent event) {
@FXML
protected void handleAboutAction(ActionEvent event) {
}
private class NetLoggerClientTab extends Tab{
public NetLoggerClientTab(String host, int port) throws IOException{
this.setText( host+":"+port );
private class NetLoggerClientTab extends Tab{
public NetLoggerClientTab(String host, int port) throws IOException{
this.setText( host+":"+port );
FXMLLoader loader = new FXMLLoader();
Parent tabRoot = loader.load(getClass().getResource("NetLogClientInstance.fxml"));
this.setContent(tabRoot);
AnchorPane.setRightAnchor(tabRoot, 0.0);
//this.setOnClosed(new EventHandler<Event>() {
// public void handle(Event e) {
// handleDisconnectAction(e);
// }
//});
}
}
Parent tabRoot = loader.load(getClass().getResource("NetLogClientInstance.fxml"));
this.setContent(tabRoot);
AnchorPane.setRightAnchor(tabRoot, 0.0);
//this.setOnClosed(new EventHandler<Event>() {
// public void handle(Event e) {
// handleDisconnectAction(e);
// }
//});
}
}
}

View file

@ -40,15 +40,15 @@ import java.util.logging.Level;
import java.util.logging.Logger;
public class NetLogGuiClientInstance implements Initializable, NetLogListener {
private static final Logger logger = LogUtil.getLogger();
private static enum Status{RUNNING, PAUSED, DISCONNECTED}
private static final Logger logger = LogUtil.getLogger();
private static enum Status{RUNNING, PAUSED, DISCONNECTED}
// Logic variables
private NetLogClient net;
private Status status;
// Logic variables
private NetLogClient net;
private Status status;
// UI elements
@FXML private ToggleButton pauseButton;
// UI elements
@FXML private ToggleButton pauseButton;
@FXML private Label levelLabel;
@FXML private ComboBox levelComboBox;
@FXML private Label intervalLabel;
@ -57,120 +57,120 @@ public class NetLogGuiClientInstance implements Initializable, NetLogListener {
@FXML private Label errorLabel;
@FXML private Label logCountLabel;
@FXML private TableView<NetLogMessage> logTable;
@FXML private TableColumn<NetLogMessage, Long> logTimestampColumn;
@FXML private TableColumn<NetLogMessage, String> logLevelColumn;
@FXML private TableColumn<NetLogMessage, String> logColumn;
@FXML private TableView<NetLogMessage> logTable;
@FXML private TableColumn<NetLogMessage, Long> logTimestampColumn;
@FXML private TableColumn<NetLogMessage, String> logLevelColumn;
@FXML private TableColumn<NetLogMessage, String> logColumn;
@FXML private TableView<NetLogExceptionMessage> exceptionTable;
@FXML private TableColumn<NetLogExceptionMessage, Long> exCountColumn;
@FXML private TableColumn<NetLogExceptionMessage, String> exNameColumn;
@FXML private TableColumn<NetLogExceptionMessage, String> exMessageColumn;
@FXML private TableColumn<NetLogExceptionMessage, String> exStackTraceColumn;
@FXML private TableView<NetLogExceptionMessage> exceptionTable;
@FXML private TableColumn<NetLogExceptionMessage, Long> exCountColumn;
@FXML private TableColumn<NetLogExceptionMessage, String> exNameColumn;
@FXML private TableColumn<NetLogExceptionMessage, String> exMessageColumn;
@FXML private TableColumn<NetLogExceptionMessage, String> exStackTraceColumn;
public void initialize(URL arg0, ResourceBundle arg1) {
// Connect to Server
try{
net = new NetLogClient("127.0.0.1", 5050);
net.addListener( this );
status = Status.RUNNING;
}catch(Exception e){
logger.log(Level.SEVERE, null, e);
status = Status.DISCONNECTED;
errorLabel.setText(e.getMessage());
}
updateStatus();
public void initialize(URL arg0, ResourceBundle arg1) {
// Connect to Server
try{
net = new NetLogClient("127.0.0.1", 5050);
net.addListener( this );
status = Status.RUNNING;
}catch(Exception e){
logger.log(Level.SEVERE, null, e);
status = Status.DISCONNECTED;
errorLabel.setText(e.getMessage());
}
updateStatus();
// Setup Gui
logTimestampColumn.setCellValueFactory(new PropertyValueFactory<NetLogMessage, Long>("timestamp"));
logLevelColumn.setCellValueFactory(new PropertyValueFactory<NetLogMessage, String>("level"));
logLevelColumn.setCellFactory(new RowCssCellFactory<NetLogMessage,String>(){
public String getStyleName(String item){
return item;
}
});
logColumn.setCellValueFactory(new PropertyValueFactory<NetLogMessage, String>("log"));
// Setup Gui
logTimestampColumn.setCellValueFactory(new PropertyValueFactory<NetLogMessage, Long>("timestamp"));
logLevelColumn.setCellValueFactory(new PropertyValueFactory<NetLogMessage, String>("level"));
logLevelColumn.setCellFactory(new RowCssCellFactory<NetLogMessage,String>(){
public String getStyleName(String item){
return item;
}
});
logColumn.setCellValueFactory(new PropertyValueFactory<NetLogMessage, String>("log"));
exCountColumn.setCellValueFactory(new PropertyValueFactory<NetLogExceptionMessage, Long>("count"));
exNameColumn.setCellValueFactory(new PropertyValueFactory<NetLogExceptionMessage, String>("name"));
exMessageColumn.setCellValueFactory(new PropertyValueFactory<NetLogExceptionMessage, String>("message"));
exStackTraceColumn.setCellValueFactory(new PropertyValueFactory<NetLogExceptionMessage, String>("stackTrace"));
}
exCountColumn.setCellValueFactory(new PropertyValueFactory<NetLogExceptionMessage, Long>("count"));
exNameColumn.setCellValueFactory(new PropertyValueFactory<NetLogExceptionMessage, String>("name"));
exMessageColumn.setCellValueFactory(new PropertyValueFactory<NetLogExceptionMessage, String>("message"));
exStackTraceColumn.setCellValueFactory(new PropertyValueFactory<NetLogExceptionMessage, String>("stackTrace"));
}
/************* NETWORK *****************/
public void handleLogMessage(NetLogMessage msg) {
if(status == Status.RUNNING){
logTable.getItems().add(msg);
/************* NETWORK *****************/
public void handleLogMessage(NetLogMessage msg) {
if(status == Status.RUNNING){
logTable.getItems().add(msg);
Platform.runLater(new Runnable() {
public void run() {
logCountLabel.setText("" + (Long.parseLong(logCountLabel.getText()) + 1));
}
});
}
}
}
}
public void handleExceptionMessage(NetLogExceptionMessage msg) {
if(status == Status.RUNNING){
exceptionTable.getItems().remove(msg);
exceptionTable.getItems().add(msg);
}
}
public void handleExceptionMessage(NetLogExceptionMessage msg) {
if(status == Status.RUNNING){
exceptionTable.getItems().remove(msg);
exceptionTable.getItems().add(msg);
}
}
public void handleStatusMessage(NetLogStatusMessage msg) {
if(status == Status.RUNNING){
}
}
public void handleStatusMessage(NetLogStatusMessage msg) {
if(status == Status.RUNNING){
/*************** GUI *******************/
@FXML
protected void handlePauseAction(ActionEvent event) {
if(status == Status.RUNNING){
status = Status.PAUSED;
logger.info("Logging paused");
}
else if(status == Status.PAUSED){
status = Status.RUNNING;
logger.info("Logging Unpaused");
}
updateStatus();
}
}
}
@FXML
protected void handleDisconnectAction(Event event) {
logger.info("Disconnecting from Log Server");
net.close();
status = Status.DISCONNECTED;
updateStatus();
}
/*************** GUI *******************/
@FXML
protected void handlePauseAction(ActionEvent event) {
if(status == Status.RUNNING){
status = Status.PAUSED;
logger.info("Logging paused");
}
else if(status == Status.PAUSED){
status = Status.RUNNING;
logger.info("Logging Unpaused");
}
updateStatus();
}
@FXML
protected void handleLevelChanged(ActionEvent event) {
logger.info("Updating Log Level");
}
@FXML
protected void handleDisconnectAction(Event event) {
logger.info("Disconnecting from Log Server");
net.close();
status = Status.DISCONNECTED;
updateStatus();
}
@FXML
protected void handleIntervalChanged(ActionEvent event) {
logger.info("Updating Log Interval");
}
@FXML
protected void handleLevelChanged(ActionEvent event) {
logger.info("Updating Log Level");
}
private void updateStatus(){
if(progressBar == null || pauseButton == null){
return;
}
@FXML
protected void handleIntervalChanged(ActionEvent event) {
logger.info("Updating Log Interval");
}
if(status == Status.RUNNING){
progressBar.setProgress(-1.0);
pauseButton.setText("Pause");
}
else if(status == Status.PAUSED){
progressBar.setProgress(1.0);
pauseButton.setText("Unpause");
}
else if(status == Status.DISCONNECTED){
pauseButton.setDisable(true);
private void updateStatus(){
if(progressBar == null || pauseButton == null){
return;
}
if(status == Status.RUNNING){
progressBar.setProgress(-1.0);
pauseButton.setText("Pause");
}
else if(status == Status.PAUSED){
progressBar.setProgress(1.0);
pauseButton.setText("Unpause");
}
else if(status == Status.DISCONNECTED){
pauseButton.setDisable(true);
levelLabel.setDisable(true);
levelComboBox.setDisable(true);
intervalLabel.setDisable(true);
@ -181,42 +181,42 @@ public class NetLogGuiClientInstance implements Initializable, NetLogListener {
progressBar.setProgress(0);
logCountLabel.setDisable(true);
}
}
}
}
/**
* http://stackoverflow.com/questions/13697115/javafx-tableview-colors
*/
public abstract class RowCssCellFactory<S,T> implements Callback<TableColumn<S,T>, TableCell<S,T>> {
/**
* http://stackoverflow.com/questions/13697115/javafx-tableview-colors
*/
public abstract class RowCssCellFactory<S,T> implements Callback<TableColumn<S,T>, TableCell<S,T>> {
public TableCell<S,T> call(TableColumn<S,T> p) {
TableCell<S, T> cell = new TableCell<S, T>() {
@Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
setText(empty ? null : getString());
setGraphic(null);
public TableCell<S,T> call(TableColumn<S,T> p) {
TableCell<S, T> cell = new TableCell<S, T>() {
@Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
setText(empty ? null : getString());
setGraphic(null);
String style = getStyleName(item);
if(style != null){
TableRow<?> row = getTableRow();
row.getStyleClass().add(style);
}
}
String style = getStyleName(item);
if(style != null){
TableRow<?> row = getTableRow();
row.getStyleClass().add(style);
}
}
@Override
public void updateSelected(boolean upd){
super.updateSelected(upd);
}
@Override
public void updateSelected(boolean upd){
super.updateSelected(upd);
}
private String getString() {
return getItem() == null ? "NULL" : getItem().toString();
}
};
return cell;
}
private String getString() {
return getItem() == null ? "NULL" : getItem().toString();
}
};
return cell;
}
public abstract String getStyleName(T item);
}
public abstract String getStyleName(T item);
}
}

View file

@ -26,18 +26,18 @@ package zutil.log.net;
public interface NetLogListener {
/**
* Handle incoming log messages
*/
public void handleLogMessage( NetLogMessage log );
/**
* Handle incoming exception messages
*/
public void handleExceptionMessage( NetLogExceptionMessage exception );
/**
* Handle incoming status messages
*/
public void handleStatusMessage( NetLogStatusMessage status );
/**
* Handle incoming log messages
*/
public void handleLogMessage( NetLogMessage log );
/**
* Handle incoming exception messages
*/
public void handleExceptionMessage( NetLogExceptionMessage exception );
/**
* Handle incoming status messages
*/
public void handleStatusMessage( NetLogStatusMessage status );
}

View file

@ -31,82 +31,82 @@ import java.util.Date;
import java.util.logging.LogRecord;
public class NetLogMessage implements Message {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
private static final SimpleDateFormat dataFormat =
new SimpleDateFormat("yyyy--MM-dd HH:mm:ss");
private long timestamp;
private String level;
private int threadID;
private String className;
private String methodName;
private String log;
private long timestamp;
private String level;
private int threadID;
private String className;
private String methodName;
private String log;
public NetLogMessage(String level, long timestamp, String log){
this.level = level;
this.timestamp = timestamp;
this.log = log;
}
public NetLogMessage(String level, long timestamp, String log){
this.level = level;
this.timestamp = timestamp;
this.log = log;
}
public NetLogMessage( LogRecord record ){
timestamp = record.getMillis();
level = record.getLevel().getName();
threadID = record.getThreadID();
className = record.getSourceClassName();
methodName = record.getSourceMethodName();
log = record.getMessage();
}
public NetLogMessage( LogRecord record ){
timestamp = record.getMillis();
level = record.getLevel().getName();
threadID = record.getThreadID();
className = record.getSourceClassName();
methodName = record.getSourceMethodName();
log = record.getMessage();
}
public String getTimestamp() {
return dataFormat.format(new Date(timestamp));
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getLevel() {
return level;
}
public String getTimestamp() {
return dataFormat.format(new Date(timestamp));
}
public void setLevel(String level) {
this.level = level;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public int getThreadID() {
return threadID;
}
public String getLevel() {
return level;
}
public void setThreadID(int threadID) {
this.threadID = threadID;
}
public void setLevel(String level) {
this.level = level;
}
public String getClassName() {
return className;
}
public int getThreadID() {
return threadID;
}
public void setClassName(String className) {
this.className = className;
}
public void setThreadID(int threadID) {
this.threadID = threadID;
}
public String getMethodName() {
return methodName;
}
public String getClassName() {
return className;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public void setClassName(String className) {
this.className = className;
}
public String getLog() {
return log;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public String getLog() {
return log;
}
public void setLog(String log) {
this.log = log;
}
public void setLog(String log) {
this.log = log;
}
}

View file

@ -42,135 +42,135 @@ import java.util.logging.Logger;
public class NetLogServer extends Handler {
private static final Logger logger = LogUtil.getLogger();
private static final Logger logger = LogUtil.getLogger();
private NetLogNetwork net;
private ConcurrentHashMap<NetLogExceptionMessage,NetLogExceptionMessage> exceptions;
private NetLogNetwork net;
private ConcurrentHashMap<NetLogExceptionMessage,NetLogExceptionMessage> exceptions;
/**
* @param port the port the server will listen on
*/
public NetLogServer(int port) {
super();
exceptions = new ConcurrentHashMap<NetLogExceptionMessage,NetLogExceptionMessage>();
net = new NetLogNetwork(port);
net.start();
}
/**
* @param port the port the server will listen on
*/
public NetLogServer(int port) {
super();
exceptions = new ConcurrentHashMap<NetLogExceptionMessage,NetLogExceptionMessage>();
net = new NetLogNetwork(port);
net.start();
}
public void publish(LogRecord record) {
// ensure that this log record should be logged by this Handler
if (!isLoggable(record))
return;
public void publish(LogRecord record) {
// ensure that this log record should be logged by this Handler
if (!isLoggable(record))
return;
// Output the formatted data to the file
if(record.getThrown() != null){
NetLogExceptionMessage exception = new NetLogExceptionMessage(record);
if(!exceptions.containsKey(exception)){
logger.finest("Received new exception: "+exception);
exceptions.put(exception, exception);
net.sendMessage( exception );
}
else{
exception = exceptions.get(exception);
exception.addCount(1);
logger.finest("Received known exception(Count: "+exception.getCount()+"): "+exception);
net.sendMessage( exception );
}
}
else{
NetLogMessage log = new NetLogMessage(record);
net.sendMessage( log );
}
}
// Output the formatted data to the file
if(record.getThrown() != null){
NetLogExceptionMessage exception = new NetLogExceptionMessage(record);
if(!exceptions.containsKey(exception)){
logger.finest("Received new exception: "+exception);
exceptions.put(exception, exception);
net.sendMessage( exception );
}
else{
exception = exceptions.get(exception);
exception.addCount(1);
logger.finest("Received known exception(Count: "+exception.getCount()+"): "+exception);
net.sendMessage( exception );
}
}
else{
NetLogMessage log = new NetLogMessage(record);
net.sendMessage( log );
}
}
public void flush() {}
public void flush() {}
public void close() {
net.close();
}
public void close() {
net.close();
}
class NetLogNetwork extends ThreadedTCPNetworkServer{
private ConcurrentLinkedQueue<NetLogServerThread> threads;
class NetLogNetwork extends ThreadedTCPNetworkServer{
private ConcurrentLinkedQueue<NetLogServerThread> threads;
public NetLogNetwork(int port) {
super(port);
threads = new ConcurrentLinkedQueue<NetLogServerThread>();
}
public NetLogNetwork(int port) {
super(port);
threads = new ConcurrentLinkedQueue<NetLogServerThread>();
}
public void sendMessage(Message log){
for( NetLogServerThread thread : threads ){
thread.sendMessage( log );
}
}
public void sendMessage(Message log){
for( NetLogServerThread thread : threads ){
thread.sendMessage( log );
}
}
@Override
protected ThreadedTCPNetworkServerThread getThreadInstance(Socket s) {
try {
NetLogServerThread thread = new NetLogServerThread(s);
return thread;
} catch (IOException e) {
logger.log(Level.SEVERE, "Unable to start Client thread", e);
}
return null;
}
@Override
protected ThreadedTCPNetworkServerThread getThreadInstance(Socket s) {
try {
NetLogServerThread thread = new NetLogServerThread(s);
return thread;
} catch (IOException e) {
logger.log(Level.SEVERE, "Unable to start Client thread", e);
}
return null;
}
class NetLogServerThread implements ThreadedTCPNetworkServerThread{
private ObjectOutputStream out;
private ObjectInputStream in;
private Socket s;
class NetLogServerThread implements ThreadedTCPNetworkServerThread{
private ObjectOutputStream out;
private ObjectInputStream in;
private Socket s;
public NetLogServerThread(Socket s) throws IOException{
this.s = s;
logger.info("Client connected: "+s.getInetAddress());
out = new ObjectOutputStream( s.getOutputStream() );
in = new ObjectInputStream( s.getInputStream() );
sendAllExceptions();
threads.add( this );
}
public NetLogServerThread(Socket s) throws IOException{
this.s = s;
logger.info("Client connected: "+s.getInetAddress());
out = new ObjectOutputStream( s.getOutputStream() );
in = new ObjectInputStream( s.getInputStream() );
public void sendMessage(Message msg){
try {
out.writeObject( msg );
out.reset();
} catch (Exception e) {
this.close();
logger.log(Level.SEVERE, "Unable to send message to client: "+s.getInetAddress(), e);
}
}
sendAllExceptions();
threads.add( this );
}
public void sendAllExceptions(){
logger.fine("Sending all exceptions to client: "+s.getInetAddress());
for(NetLogExceptionMessage e : exceptions.values())
sendMessage(e);
}
public void sendMessage(Message msg){
try {
out.writeObject( msg );
out.reset();
} catch (Exception e) {
this.close();
logger.log(Level.SEVERE, "Unable to send message to client: "+s.getInetAddress(), e);
}
}
public void run() {
try {
while( true ){
in.readObject();
}
} catch (Exception e) {
logger.log(Level.SEVERE, null, e);
} finally {
this.close();
}
}
public void sendAllExceptions(){
logger.fine("Sending all exceptions to client: "+s.getInetAddress());
for(NetLogExceptionMessage e : exceptions.values())
sendMessage(e);
}
public void run() {
try {
while( true ){
in.readObject();
}
} catch (Exception e) {
logger.log(Level.SEVERE, null, e);
} finally {
this.close();
}
}
public void close(){
try {
threads.remove(this);
logger.info("Client disconnected: "+s.getInetAddress());
out.close();
s.close();
} catch (IOException e) {
logger.log(Level.SEVERE, "Unable to close Client Socket", e);
}
}
}
}
public void close(){
try {
threads.remove(this);
logger.info("Client disconnected: "+s.getInetAddress());
out.close();
s.close();
} catch (IOException e) {
logger.log(Level.SEVERE, "Unable to close Client Socket", e);
}
}
}
}
}

View file

@ -27,8 +27,8 @@ package zutil.log.net;
import zutil.net.nio.message.Message;
public class NetLogStatusMessage implements Message{
private static final long serialVersionUID = 1L;
public long totalMemory;
public long freememory;
private static final long serialVersionUID = 1L;
public long totalMemory;
public long freememory;
}

View file

@ -26,100 +26,100 @@ package zutil.math;
public class Tick {
/**
* Ticks a given string(increments the string with one)
*
* @param ts is the string to tick
* @param maxChar is the maximum number of characters in the string
* @return the ticked string
*/
public static String tick(String ts, int maxChar){
StringBuffer ret = new StringBuffer(ts.trim());
int index = ret.length()-1;
if(ret.length() < maxChar){
ret.append('a');
}
else{
while(index >= 0){
char c = increment(ret.charAt(index));
if(c != 0){
if(index == 0 && ret.length() < maxChar) ret.append('a');
if(index == 0) ret = new StringBuffer(""+c);
else ret.setCharAt(index,c);
break;
}
else{
//ret.setCharAt(index,'a');
ret.deleteCharAt(index);
index--;
}
}
}
return ret.toString();
}
/**
* Increments the char with one after the swedish alfabet
*
* @param c is the char to increment
* @return the incremented char in lowercase 0 if it reached the end
*/
public static char increment(char c){
switch(Character.toLowerCase(c)){
case 'z': return (char)134;
case (char)134: return (char)132;
case (char)132: return (char)148;
}
c = (char)(Character.toLowerCase(c) + 1);
if(isAlphabetic(c)){
return c;
}
return 0;
}
/**
* Checks if the char is a valid character in
* the Swedish alphabet
*
* @param c is the char to check
* @return true if the char is a valid letter
*/
public static boolean isAlphabetic(char c){
switch(Character.toLowerCase(c)){
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
case (char)134:
case (char)132:
case (char)148:
/**
* Ticks a given string(increments the string with one)
*
* @param ts is the string to tick
* @param maxChar is the maximum number of characters in the string
* @return the ticked string
*/
public static String tick(String ts, int maxChar){
StringBuffer ret = new StringBuffer(ts.trim());
int index = ret.length()-1;
if(ret.length() < maxChar){
ret.append('a');
}
else{
while(index >= 0){
char c = increment(ret.charAt(index));
if(c != 0){
if(index == 0 && ret.length() < maxChar) ret.append('a');
if(index == 0) ret = new StringBuffer(""+c);
else ret.setCharAt(index,c);
break;
}
else{
//ret.setCharAt(index,'a');
ret.deleteCharAt(index);
index--;
}
}
}
return ret.toString();
}
/**
* Increments the char with one after the swedish alfabet
*
* @param c is the char to increment
* @return the incremented char in lowercase 0 if it reached the end
*/
public static char increment(char c){
switch(Character.toLowerCase(c)){
case 'z': return (char)134;
case (char)134: return (char)132;
case (char)132: return (char)148;
}
c = (char)(Character.toLowerCase(c) + 1);
if(isAlphabetic(c)){
return c;
}
return 0;
}
/**
* Checks if the char is a valid character in
* the Swedish alphabet
*
* @param c is the char to check
* @return true if the char is a valid letter
*/
public static boolean isAlphabetic(char c){
switch(Character.toLowerCase(c)){
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
case (char)134:
case (char)132:
case (char)148:
return true;
default:
default:
return false;
}
}
}
}
}

View file

@ -81,285 +81,285 @@ public class FTPClient extends Thread{
return UNKNOWN;
}
}
//***************************************************
//***************************************************
private FTPConnectionType connectionType;
private BufferedReader in;
private Writer out;
private Socket socket;
private long last_sent;
private BufferedReader in;
private Writer out;
private Socket socket;
private long last_sent;
/**
* Creates a FTP connection and logs in
*
* @param url the address to server
* @param port port number
* @param user login username
* @param pass password
* @param conn_type connection type
*/
public FTPClient(String url, int port, String user, String pass, FTPConnectionType conn_type) throws UnknownHostException, IOException, AccountException{
socket = new Socket(url, port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new OutputStreamWriter(socket.getOutputStream());
/**
* Creates a FTP connection and logs in
*
* @param url the address to server
* @param port port number
* @param user login username
* @param pass password
* @param conn_type connection type
*/
public FTPClient(String url, int port, String user, String pass, FTPConnectionType conn_type) throws UnknownHostException, IOException, AccountException{
socket = new Socket(url, port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new OutputStreamWriter(socket.getOutputStream());
connectionType = conn_type;
readCommand();
sendCommand("USER "+user);
sendNoReplyCommand("PASS "+pass);
String tmp = readCommand();
if(parseReturnCode(tmp) == FTPReturnCode.LOGIN_NO){
close();
throw new AccountException(tmp);
}
start();
}
readCommand();
sendCommand("USER "+user);
sendNoReplyCommand("PASS "+pass);
String tmp = readCommand();
if(parseReturnCode(tmp) == FTPReturnCode.LOGIN_NO){
close();
throw new AccountException(tmp);
}
start();
}
//**************************************************************************************
//********************************* Command channel ************************************
/**
* Sends the given command to the server and returns a status integer
*
* @return last line received from the server
*/
private FTPReturnCode sendCommand(String cmd) throws IOException{
sendNoReplyCommand(cmd);
return parseReturnCode( readCommand( ) );
}
/**
* Sends a command and don't cares about the reply
*/
private void sendNoReplyCommand(String cmd) throws IOException{
last_sent = System.currentTimeMillis();
out.append(cmd).append('\n');
}
/**
* Reads from the command channel until there are nothing
* left to read and returns the last line
*
* @return last line received by the server
*/
private String readCommand() throws IOException{
String tmp = in.readLine();
while(!Character.isWhitespace(tmp.charAt(3))){
tmp = in.readLine();
/**
* Sends the given command to the server and returns a status integer
*
* @return last line received from the server
*/
private FTPReturnCode sendCommand(String cmd) throws IOException{
sendNoReplyCommand(cmd);
return parseReturnCode( readCommand( ) );
}
/**
* Sends a command and don't cares about the reply
*/
private void sendNoReplyCommand(String cmd) throws IOException{
last_sent = System.currentTimeMillis();
out.append(cmd).append('\n');
}
/**
* Reads from the command channel until there are nothing
* left to read and returns the last line
*
* @return last line received by the server
*/
private String readCommand() throws IOException{
String tmp = in.readLine();
while(!Character.isWhitespace(tmp.charAt(3))){
tmp = in.readLine();
if(parseReturnCode(tmp).isError()) throw new IOException(tmp);
}
return tmp;
}
/**
* Parses the return line from the server and returns the status code
*
* @param msg message String from the server
* @return a status code response
*/
private FTPReturnCode parseReturnCode(String msg){
return FTPReturnCode.fromCode(Integer.parseInt(msg.substring(0, 3)));
}
}
return tmp;
}
/**
* Parses the return line from the server and returns the status code
*
* @param msg message String from the server
* @return a status code response
*/
private FTPReturnCode parseReturnCode(String msg){
return FTPReturnCode.fromCode(Integer.parseInt(msg.substring(0, 3)));
}
//**************************************************************************************
//****************************** File system actions ************************************
/**
* Returns a LinkedList with names of all the files in the directory
*
/**
* Returns a LinkedList with names of all the files in the directory
*
* @deprecated
* @return List with filenames
*/
public String[] getFileList(String path) throws IOException{
BufferedInputStream data_in = getDataInputStream();
sendCommand("NLST "+path);
String data = new String(IOUtil.readContent(data_in));
data_in.close();
readCommand();
return data.split("[\n\r]");
}
/**
* Returns information about a file or directory
*
* @deprecated
* @return a List of Strings with information
*/
public String getFileInfo(String path) throws IOException{
Pattern regex = Pattern.compile("\\s{1,}");
BufferedInputStream data_in = getDataInputStream();
sendCommand("LIST "+path);
* @return List with filenames
*/
public String[] getFileList(String path) throws IOException{
BufferedInputStream data_in = getDataInputStream();
sendCommand("NLST "+path);
String data = new String(IOUtil.readContent(data_in));
data_in.close();
readCommand();
return data;
}
/**
* Creates a file in the server with the given data
*
* @param path filepath
* @param data data to put in the file
*/
public void sendFile(String path, String data) throws IOException{
BufferedOutputStream data_out = getDataOutputStream();
sendCommand("STOR "+path);
data_in.close();
readCommand();
return data.split("[\n\r]");
}
/**
* Returns information about a file or directory
*
* @deprecated
* @return a List of Strings with information
*/
public String getFileInfo(String path) throws IOException{
Pattern regex = Pattern.compile("\\s{1,}");
BufferedInputStream data_in = getDataInputStream();
sendCommand("LIST "+path);
String data = new String(IOUtil.readContent(data_in));
data_in.close();
readCommand();
return data;
}
/**
* Creates a file in the server with the given data
*
* @param path filepath
* @param data data to put in the file
*/
public void sendFile(String path, String data) throws IOException{
BufferedOutputStream data_out = getDataOutputStream();
sendCommand("STOR "+path);
byte[] byte_data = data.getBytes();
data_out.write(byte_data, 0, byte_data.length);
data_out.close();
data_out.write(byte_data, 0, byte_data.length);
data_out.close();
readCommand();
}
/**
* Creates a directory in the server
*
* @param path The path to the directory
*/
public boolean createDir(String path) throws IOException{
if(sendCommand("MKD "+path) == FTPReturnCode.PATH_CREATED)
return true;
return false;
}
/**
* Returns a InputStream for a file on the server
* WARNING: you must run readCommand(); after you close the stream
*
* @return a stream with file data
*/
private BufferedInputStream getFileInputStream(String path) throws IOException{
readCommand();
}
/**
* Creates a directory in the server
*
* @param path The path to the directory
*/
public boolean createDir(String path) throws IOException{
if(sendCommand("MKD "+path) == FTPReturnCode.PATH_CREATED)
return true;
return false;
}
/**
* Returns a InputStream for a file on the server
* WARNING: you must run readCommand(); after you close the stream
*
* @return a stream with file data
*/
private BufferedInputStream getFileInputStream(String path) throws IOException{
BufferedInputStream input = getDataInputStream();
sendCommand("RETR "+path);
return input;
}
/**
* Download a file from the server to a local file
*
* @param source source file on the server
* @param destination local destination file
*/
public void getFile(String source, String destination) throws IOException{
sendCommand("RETR "+path);
return input;
}
/**
* Download a file from the server to a local file
*
* @param source source file on the server
* @param destination local destination file
*/
public void getFile(String source, String destination) throws IOException{
BufferedInputStream ext_file_in = getFileInputStream(source);
BufferedOutputStream local_file_out = new BufferedOutputStream(new FileOutputStream(new File(destination)));
BufferedOutputStream local_file_out = new BufferedOutputStream(new FileOutputStream(new File(destination)));
IOUtil.copyStream(ext_file_in, local_file_out);
readCommand();
}
/**
* Remove a file from the FTP server
*
* @return true if the command was successful, false otherwise
*/
public boolean removeFile(String path) throws IOException{
if(sendCommand("DELE "+path) == FTPReturnCode.FILE_ACTION_OK)
return true;
return false;
}
/**
* Removes a directory from the FTP server
*
* @return True if the command was successful or false otherwise
*/
public boolean removeDir(String path) throws IOException{
if(sendCommand("RMD "+path) == FTPReturnCode.FILE_ACTION_OK)
return true;
return false;
}
readCommand();
}
/**
* Remove a file from the FTP server
*
* @return true if the command was successful, false otherwise
*/
public boolean removeFile(String path) throws IOException{
if(sendCommand("DELE "+path) == FTPReturnCode.FILE_ACTION_OK)
return true;
return false;
}
/**
* Removes a directory from the FTP server
*
* @return True if the command was successful or false otherwise
*/
public boolean removeDir(String path) throws IOException{
if(sendCommand("RMD "+path) == FTPReturnCode.FILE_ACTION_OK)
return true;
return false;
}
//**************************************************************************************
//******************************** Data Connection *************************************
/**
* Start a data connection to the server.
*
* @return a PrintStream for the channel
*/
public BufferedOutputStream getDataOutputStream() throws IOException{
/**
* Start a data connection to the server.
*
* @return a PrintStream for the channel
*/
public BufferedOutputStream getDataOutputStream() throws IOException{
if(connectionType == FTPConnectionType.PASSIVE){ // Passive Mode
int port = setPassiveMode();
Socket data_socket = new Socket(socket.getInetAddress().getHostAddress(), port);
return new BufferedOutputStream(data_socket.getOutputStream());
}
else{ // Active Mode
return null;
}
}
/**
* Start a data connection to the server.
*
* @return a BufferedReader for the data channel
*/
public BufferedInputStream getDataInputStream() throws IOException{
if(connectionType == FTPConnectionType.PASSIVE){ // Passive Mode
int port = setPassiveMode();
}
else{ // Active Mode
return null;
}
}
/**
* Start a data connection to the server.
*
* @return a BufferedReader for the data channel
*/
public BufferedInputStream getDataInputStream() throws IOException{
if(connectionType == FTPConnectionType.PASSIVE){ // Passive Mode
int port = setPassiveMode();
Socket data_socket = new Socket(socket.getInetAddress().getHostAddress(), port);
return new BufferedInputStream(data_socket.getInputStream());
}
else{ // Active Mode
return null;
}
}
}
else{ // Active Mode
return null;
}
}
/**
* Sets Passive mode to the server
*
* @return a port number for data channel
*/
private int setPassiveMode() throws IOException{
sendNoReplyCommand("PASV");
/**
* Sets Passive mode to the server
*
* @return a port number for data channel
*/
private int setPassiveMode() throws IOException{
sendNoReplyCommand("PASV");
String ret_msg = readCommand();
if(parseReturnCode(ret_msg) != FTPReturnCode.ENTERING_PASSIVE){
throw new IOException("Passive mode rejected by server: "+ret_msg);
}
if(parseReturnCode(ret_msg) != FTPReturnCode.ENTERING_PASSIVE){
throw new IOException("Passive mode rejected by server: "+ret_msg);
}
ret_msg = ret_msg.substring(ret_msg.indexOf('(')+1, ret_msg.indexOf(')'));
String[] tmpArray = ret_msg.split("[,]");
if(tmpArray.length <= 1)
return Integer.parseInt(tmpArray[0]);
else
return Integer.parseInt(tmpArray[4])*256 + Integer.parseInt(tmpArray[5]);
}
//**************************************************************************************
//**************************************************************************************
/**
* Keep the connection alive
*/
public void run(){
try {
while(true){
if(last_sent > System.currentTimeMillis() + FTP_NOOP_INT*1000){
sendCommand("NOOP");
}
try{ Thread.sleep(5000); }catch(Exception e){}
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
String[] tmpArray = ret_msg.split("[,]");
/**
* Close the FTP connection
*/
public void close() throws IOException{
sendCommand("QUIT");
in.close();
out.close();
socket.close();
this.interrupt();
}
if(tmpArray.length <= 1)
return Integer.parseInt(tmpArray[0]);
else
return Integer.parseInt(tmpArray[4])*256 + Integer.parseInt(tmpArray[5]);
}
//**************************************************************************************
//**************************************************************************************
/**
* Keep the connection alive
*/
public void run(){
try {
while(true){
if(last_sent > System.currentTimeMillis() + FTP_NOOP_INT*1000){
sendCommand("NOOP");
}
try{ Thread.sleep(5000); }catch(Exception e){}
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
/**
* Close the FTP connection
*/
public void close() throws IOException{
sendCommand("QUIT");
in.close();
out.close();
socket.close();
this.interrupt();
}
}

View file

@ -42,299 +42,299 @@ import java.net.UnknownHostException;
*
*/
public class POP3Client {
public static boolean DEBUG = false;
public static final int POP3_PORT = 110;
public static final int POP3_SSL_PORT = 995;
public static boolean DEBUG = false;
public static final int POP3_PORT = 110;
public static final int POP3_SSL_PORT = 995;
private BufferedReader in;
private PrintStream out;
private Socket socket;
private BufferedReader in;
private PrintStream out;
private Socket socket;
/**
* Connect to a POP3 server without username
*
* @param host The hostname of the server
* @throws UnknownHostException
* @throws IOException
*/
public POP3Client(String host) throws UnknownHostException, IOException{
this(host, POP3_PORT, null, null, false);
}
/**
* Connect to a POP3 server with username and password
*
* @param host The hostname of the server
* @param user The username
* @param password the password
* @throws UnknownHostException
* @throws IOException
*/
public POP3Client(String host, String user, String password) throws UnknownHostException, IOException{
this(host, POP3_PORT, user, password, false);
}
/**
* Connects to a POP3 server with username and password and SSL
*
* @param host The hostname of the server
* @param user The username
* @param password the password
* @param ssl If SSL should be used
* @throws UnknownHostException
* @throws IOException
*/
public POP3Client(String host, String user, String password, boolean ssl) throws UnknownHostException, IOException{
this(host, (ssl ? POP3_SSL_PORT : POP3_PORT), user, password, ssl);
}
/**
* Connect to a POP3 server without username
*
* @param host The hostname of the server
* @throws UnknownHostException
* @throws IOException
*/
public POP3Client(String host) throws UnknownHostException, IOException{
this(host, POP3_PORT, null, null, false);
}
/**
* Connects to a POP3 server with username and password and
* SSL and with costume port.
*
* @param host The hostname of the server
* @param port The port number to connect to on the server
* @param user The username
* @param password the password
* @param ssl If SSL should be used
* @throws UnknownHostException
* @throws IOException
*/
public POP3Client(String host, int port, String user, String password, boolean ssl) throws UnknownHostException, IOException{
if(ssl) connectSSL(host, port);
else connect(host, port);
if(user != null){
login(user, password);
}
}
/**
* Connects to the server
*
* @param host The hostname of the server
* @param port The port to connect to on the server
* @throws UnknownHostException
* @throws IOException
*/
private void connect(String host, int port) throws UnknownHostException, IOException{
socket = new Socket(host, port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintStream(socket.getOutputStream());
/**
* Connect to a POP3 server with username and password
*
* @param host The hostname of the server
* @param user The username
* @param password the password
* @throws UnknownHostException
* @throws IOException
*/
public POP3Client(String host, String user, String password) throws UnknownHostException, IOException{
this(host, POP3_PORT, user, password, false);
}
readCommand(true);
}
/**
* Connects to the server with SSL.
* http://www.exampledepot.com/egs/javax.net.ssl/Client.html
*
* @param host The hostname of the server
* @param port The port to connect to on the server
* @throws UnknownHostException
* @throws IOException
*/
private void connectSSL(String host, int port) throws UnknownHostException, IOException{
SocketFactory socketFactory = SSLSocketFactory.getDefault();
socket = socketFactory.createSocket(host, port);
/**
* Connects to a POP3 server with username and password and SSL
*
* @param host The hostname of the server
* @param user The username
* @param password the password
* @param ssl If SSL should be used
* @throws UnknownHostException
* @throws IOException
*/
public POP3Client(String host, String user, String password, boolean ssl) throws UnknownHostException, IOException{
this(host, (ssl ? POP3_SSL_PORT : POP3_PORT), user, password, ssl);
}
/**
* Connects to a POP3 server with username and password and
* SSL and with costume port.
*
* @param host The hostname of the server
* @param port The port number to connect to on the server
* @param user The username
* @param password the password
* @param ssl If SSL should be used
* @throws UnknownHostException
* @throws IOException
*/
public POP3Client(String host, int port, String user, String password, boolean ssl) throws UnknownHostException, IOException{
if(ssl) connectSSL(host, port);
else connect(host, port);
if(user != null){
login(user, password);
}
}
/**
* Connects to the server
*
* @param host The hostname of the server
* @param port The port to connect to on the server
* @throws UnknownHostException
* @throws IOException
*/
private void connect(String host, int port) throws UnknownHostException, IOException{
socket = new Socket(host, port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintStream(socket.getOutputStream());
readCommand(true);
}
/**
* Connects to the server with SSL.
* http://www.exampledepot.com/egs/javax.net.ssl/Client.html
*
* @param host The hostname of the server
* @param port The port to connect to on the server
* @throws UnknownHostException
* @throws IOException
*/
private void connectSSL(String host, int port) throws UnknownHostException, IOException{
SocketFactory socketFactory = SSLSocketFactory.getDefault();
socket = socketFactory.createSocket(host, port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintStream(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintStream(socket.getOutputStream());
readCommand(DEBUG);
}
readCommand(DEBUG);
}
/**
* Logs in to the POP3 server with the username and password if the password is set
*
* @param user The user name
* @param password The password or null if no password is required
* @throws IOException
*/
private void login(String user, String password) throws IOException{
sendCommand("USER "+user);
if(password != null){
sendNoReplyCommand("PASS "+password, false);
if(DEBUG)System.out.println("PASS ***");
readCommand(DEBUG);
}
}
/**
* Returns the number of messages that is on the server
*
* @return Message count
* @throws IOException
*/
public int getMessageCount() throws IOException{
String msg = sendCommand("STAT", DEBUG);
return Integer.parseInt(
msg.substring(
msg.indexOf(' ')+1,
msg.indexOf(' ', msg.indexOf(' ')+1)));
}
/**
* Retrieves the message with the given id.
*
* @param id The id of the message to get
* @return The message
* @throws IOException
*/
public String getMessage(int id) throws IOException{
sendCommand("RETR "+id);
return readMultipleLines(DEBUG);
}
/**
* Returns the title of the message
*
* @param id The message id
* @return The title
* @throws IOException
*/
public String getMessageTitle(int id) throws IOException{
String tmp = getMessageHeader(id);
String tmp2 = tmp.toLowerCase();
if(tmp2.contains("subject:")){
return tmp.substring(
tmp2.indexOf("subject:")+8,
tmp2.indexOf('\n',
tmp2.indexOf("subject:")));
}
else
return null;
}
/**
* Returns the header of the given message id.
*
* @param id The id of the message to get
* @return The message
* @throws IOException
*/
public String getMessageHeader(int id) throws IOException{
sendCommand("TOP "+id+" 0");
return readMultipleLines(DEBUG);
}
/**
* Deletes the message with the given id
*
* @param id The id of the message to be deleted
* @throws IOException
*/
public void delete(int id) throws IOException{
sendCommand("DELE "+id);
}
/**
* Logs in to the POP3 server with the username and password if the password is set
*
* @param user The user name
* @param password The password or null if no password is required
* @throws IOException
*/
private void login(String user, String password) throws IOException{
sendCommand("USER "+user);
if(password != null){
sendNoReplyCommand("PASS "+password, false);
if(DEBUG)System.out.println("PASS ***");
readCommand(DEBUG);
}
}
/**
* Returns the number of messages that is on the server
*
* @return Message count
* @throws IOException
*/
public int getMessageCount() throws IOException{
String msg = sendCommand("STAT", DEBUG);
return Integer.parseInt(
msg.substring(
msg.indexOf(' ')+1,
msg.indexOf(' ', msg.indexOf(' ')+1)));
}
/**
* Retrieves the message with the given id.
*
* @param id The id of the message to get
* @return The message
* @throws IOException
*/
public String getMessage(int id) throws IOException{
sendCommand("RETR "+id);
return readMultipleLines(DEBUG);
}
/**
* Returns the title of the message
*
* @param id The message id
* @return The title
* @throws IOException
*/
public String getMessageTitle(int id) throws IOException{
String tmp = getMessageHeader(id);
String tmp2 = tmp.toLowerCase();
if(tmp2.contains("subject:")){
return tmp.substring(
tmp2.indexOf("subject:")+8,
tmp2.indexOf('\n',
tmp2.indexOf("subject:")));
}
else
return null;
}
/**
* Returns the header of the given message id.
*
* @param id The id of the message to get
* @return The message
* @throws IOException
*/
public String getMessageHeader(int id) throws IOException{
sendCommand("TOP "+id+" 0");
return readMultipleLines(DEBUG);
}
/**
* Deletes the message with the given id
*
* @param id The id of the message to be deleted
* @throws IOException
*/
public void delete(int id) throws IOException{
sendCommand("DELE "+id);
}
//*********************** IO Stuff *********************************************
/**
* Sends the given line to the server and returns a status integer
*
* @param cmd The command to send
* @return The return code from the server
* @throws IOException if the cmd fails
*/
private boolean sendCommand(String cmd) throws IOException{
return parseReturnCode(sendCommand(cmd, DEBUG));
}
/**
* Sends the given line to the server and returns the last line
*
* @param cmd The command to send
* @param print To print out the received lines
* @return Last String line from the server
* @throws IOException
*/
private String sendCommand(String cmd, boolean print) throws IOException{
sendNoReplyCommand(cmd, print);
return readCommand(print);
}
/**
* Sends the given line to the server and returns a status integer
*
* @param cmd The command to send
* @return The return code from the server
* @throws IOException if the cmd fails
*/
private boolean sendCommand(String cmd) throws IOException{
return parseReturnCode(sendCommand(cmd, DEBUG));
}
/**
* Sends a given command and don't cares about the reply
*
* @param cmd The command
* @param print If it should print to System.out
* @throws IOException
*/
private void sendNoReplyCommand(String cmd, boolean print) throws IOException{
out.println(cmd);
if(print)System.out.println(cmd);
}
/**
* Sends the given line to the server and returns the last line
*
* @param cmd The command to send
* @param print To print out the received lines
* @return Last String line from the server
* @throws IOException
*/
private String sendCommand(String cmd, boolean print) throws IOException{
sendNoReplyCommand(cmd, print);
return readCommand(print);
}
/**
* Reads on line from the command channel
*
* @param print If the method should print the input line
* @return The input line
* @throws IOException if the server returns a error code
*/
private String readCommand(boolean print) throws IOException{
String tmp = in.readLine();
if(print)System.out.println(tmp);
if( !parseReturnCode(tmp) ) throw new IOException(tmp);
/**
* Sends a given command and don't cares about the reply
*
* @param cmd The command
* @param print If it should print to System.out
* @throws IOException
*/
private void sendNoReplyCommand(String cmd, boolean print) throws IOException{
out.println(cmd);
if(print)System.out.println(cmd);
}
return tmp;
}
/**
* Reads on line from the command channel
*
* @param print If the method should print the input line
* @return The input line
* @throws IOException if the server returns a error code
*/
private String readCommand(boolean print) throws IOException{
String tmp = in.readLine();
if(print)System.out.println(tmp);
if( !parseReturnCode(tmp) ) throw new IOException(tmp);
/**
* Reads from the server until there are a line with
* only one '.'
*
* @param print To print out the received lines
* @return String with the text
* @throws IOException
*/
private String readMultipleLines(boolean print) throws IOException{
StringBuffer msg = new StringBuffer();
String tmp = in.readLine();
while(!tmp.equals(".")){
msg.append(tmp);
msg.append('\n');
tmp = in.readLine();
if(print)System.out.println(tmp);
}
return msg.toString();
}
return tmp;
}
/**
* Reads from the server until there are a line with
* only one '.'
*
* @param print To print out the received lines
* @return String with the text
* @throws IOException
*/
private String readMultipleLines(boolean print) throws IOException{
StringBuffer msg = new StringBuffer();
String tmp = in.readLine();
while(!tmp.equals(".")){
msg.append(tmp);
msg.append('\n');
tmp = in.readLine();
if(print)System.out.println(tmp);
}
return msg.toString();
}
/**
* Parses the return line from the server and returns the status code
*
* @param msg The message from the server
* @return Returns true if return code is OK false if it is ERR
* @throws IOException
*/
private boolean parseReturnCode(String msg){
int endpos = (msg.indexOf(' ')<0 ? msg.length() : msg.indexOf(' '));
return msg.substring(0, endpos).equals("+OK");
}
/**
* Parses the return line from the server and returns the status code
*
* @param msg The message from the server
* @return Returns true if return code is OK false if it is ERR
* @throws IOException
*/
private boolean parseReturnCode(String msg){
int endpos = (msg.indexOf(' ')<0 ? msg.length() : msg.indexOf(' '));
return msg.substring(0, endpos).equals("+OK");
}
//*********************************************************************************
/**
* All the delete marked messages are unmarkt
* @throws IOException
*/
public void reset() throws IOException{
sendCommand("RSET", DEBUG);
}
/**
* All the delete marked messages are unmarkt
* @throws IOException
*/
public void reset() throws IOException{
sendCommand("RSET", DEBUG);
}
/**
* All the changes(DELETE) are performed and then the connection is closed
*
* @throws IOException
*/
public void close() throws IOException{
sendCommand("QUIT", DEBUG);
in.close();
out.close();
socket.close();
}
/**
* All the changes(DELETE) are performed and then the connection is closed
*
* @throws IOException
*/
public void close() throws IOException{
sendCommand("QUIT", DEBUG);
in.close();
out.close();
socket.close();
}
}

View file

@ -40,58 +40,58 @@ import java.net.MulticastSocket;
*
*/
public class ServerFind extends Thread {
public String broadcastAddress = "230.0.0.1";
private InetAddress group;
private MulticastSocket Msocket;
public String broadcastAddress = "230.0.0.1";
private boolean avsluta;
private int port;
private InetAddress group;
private MulticastSocket Msocket;
/**
* Creates a ServerFind Thread an the specified port
*
* @param port The port to run the ServerFind Server on
* @throws IOException
*/
public ServerFind (int port) throws IOException {
this.port = port;
avsluta = false;
group = InetAddress.getByName(broadcastAddress);
Msocket = new MulticastSocket(port);
Msocket.joinGroup(group);
private boolean avsluta;
private int port;
start();
}
/**
* Creates a ServerFind Thread an the specified port
*
* @param port The port to run the ServerFind Server on
* @throws IOException
*/
public ServerFind (int port) throws IOException {
this.port = port;
avsluta = false;
group = InetAddress.getByName(broadcastAddress);
Msocket = new MulticastSocket(port);
Msocket.joinGroup(group);
public void run (){
byte[] buf = new byte[256];
DatagramPacket packet;
DatagramSocket lan_socket = null;
while (!avsluta){
try {
packet = new DatagramPacket(buf, buf.length);
Msocket.receive(packet);
start();
}
lan_socket = new DatagramSocket(port , packet.getAddress());
packet = new DatagramPacket(buf, buf.length, group, port);
lan_socket.send(packet);
lan_socket.close();
} catch (Exception e) {
MultiPrintStream.out.println("Error Establishing ServerFind Connection!!!\n" + e);
e.printStackTrace();
}
}
close();
}
public void run (){
byte[] buf = new byte[256];
DatagramPacket packet;
DatagramSocket lan_socket = null;
/**
* Closes the broadcast socket
*/
public void close(){
avsluta = true;
Msocket.close();
}
while (!avsluta){
try {
packet = new DatagramPacket(buf, buf.length);
Msocket.receive(packet);
lan_socket = new DatagramSocket(port , packet.getAddress());
packet = new DatagramPacket(buf, buf.length, group, port);
lan_socket.send(packet);
lan_socket.close();
} catch (Exception e) {
MultiPrintStream.out.println("Error Establishing ServerFind Connection!!!\n" + e);
e.printStackTrace();
}
}
close();
}
/**
* Closes the broadcast socket
*/
public void close(){
avsluta = true;
Msocket.close();
}
}

View file

@ -37,38 +37,38 @@ import java.net.MulticastSocket;
*
*/
public class ServerFindClient{
public String broadcastAddress = "230.0.0.1";
private int port;
public String broadcastAddress = "230.0.0.1";
/**
* Creates a ServerFind Client
*
* @param port The port to contact the server on
*/
public ServerFindClient(int port){
this.port = port;
}
/**
* Requests IP from server
*
* @return The address of the server
* @throws IOException
*/
public InetAddress find() throws IOException{
InetAddress group = InetAddress.getByName(broadcastAddress);
DatagramSocket lan_socket = new DatagramSocket();
MulticastSocket Msocket = new MulticastSocket(port);
Msocket.joinGroup(group);
private int port;
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port);
lan_socket.send(packet);
packet = new DatagramPacket(buf, buf.length);
Msocket.receive(packet);
/**
* Creates a ServerFind Client
*
* @param port The port to contact the server on
*/
public ServerFindClient(int port){
this.port = port;
}
return packet.getAddress();
}
/**
* Requests IP from server
*
* @return The address of the server
* @throws IOException
*/
public InetAddress find() throws IOException{
InetAddress group = InetAddress.getByName(broadcastAddress);
DatagramSocket lan_socket = new DatagramSocket();
MulticastSocket Msocket = new MulticastSocket(port);
Msocket.joinGroup(group);
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port);
lan_socket.send(packet);
packet = new DatagramPacket(buf, buf.length);
Msocket.receive(packet);
return packet.getAddress();
}
}

View file

@ -41,53 +41,53 @@ import java.util.HashMap;
*/
public class HttpClient implements AutoCloseable{
public static enum HttpRequestType{
GET, POST
}
GET, POST
}
// Request variables
private HttpURL url;
private HttpRequestType type;
private HashMap<String,String> headers;
private HashMap<String,String> cookies;
// Request variables
private HttpURL url;
private HttpRequestType type;
private HashMap<String,String> headers;
private HashMap<String,String> cookies;
private String data;
// Response variables
// Response variables
private HttpHeaderParser rspHeader;
private InputStream rspStream;
public HttpClient(HttpRequestType type){
this.type = type;
headers = new HashMap<String,String>();
cookies = new HashMap<String,String>();
}
public void setURL( URL url){
this.url = new HttpURL( url );
}
/**
* Adds a parameter to the request
*/
public void setParameter( String key, String value ){
url.setParameter(key, value);
}
/**
* Adds a cookie to the request
*/
public void setCookie( String key, String value ){
cookies.put(key, value);
}
/**
* Adds a header value to the request
*/
public void setHeader( String key, String value ){
headers.put(key, value);
}
public HttpClient(HttpRequestType type){
this.type = type;
headers = new HashMap<String,String>();
cookies = new HashMap<String,String>();
}
public void setURL( URL url){
this.url = new HttpURL( url );
}
/**
* Adds a parameter to the request
*/
public void setParameter( String key, String value ){
url.setParameter(key, value);
}
/**
* Adds a cookie to the request
*/
public void setCookie( String key, String value ){
cookies.put(key, value);
}
/**
* Adds a header value to the request
*/
public void setHeader( String key, String value ){
headers.put(key, value);
}
/**
* Sets the content data that will be included in the request.
@ -101,38 +101,38 @@ public class HttpClient implements AutoCloseable{
* Will send a HTTP request to the target host.
* NOTE: any previous request connections will be closed
*/
public HttpHeaderParser send() throws IOException{
Socket conn = new Socket( url.getHost(), url.getPort());
// Request
HttpPrintStream request = new HttpPrintStream( conn.getOutputStream(), HttpMessageType.REQUEST );
request.setRequestType( type.toString() );
request.setRequestURL( url.getHttpURL() );
request.setHeaders( headers );
request.setCookies( cookies );
if( type == HttpRequestType.POST ){
String postData = null;
public HttpHeaderParser send() throws IOException{
Socket conn = new Socket( url.getHost(), url.getPort());
// Request
HttpPrintStream request = new HttpPrintStream( conn.getOutputStream(), HttpMessageType.REQUEST );
request.setRequestType( type.toString() );
request.setRequestURL( url.getHttpURL() );
request.setHeaders( headers );
request.setCookies( cookies );
if( type == HttpRequestType.POST ){
String postData = null;
if(data != null)
postData = data;
else
postData = url.getParameterString();
request.setHeader("Content-Length", ""+postData.length());
request.println();
request.print( postData );
}
else
request.println();
request.close();
// Response
request.setHeader("Content-Length", ""+postData.length());
request.println();
request.print( postData );
}
else
request.println();
request.close();
// Response
if(rspHeader != null || rspStream != null) // Close previous request
this.close();
rspStream = new BufferedInputStream(conn.getInputStream());
rspHeader = new HttpHeaderParser(rspStream);
rspStream = new BufferedInputStream(conn.getInputStream());
rspHeader = new HttpHeaderParser(rspStream);
return rspHeader;
}
return rspHeader;
}
public HttpHeaderParser getResponseHeader(){
return rspHeader;

View file

@ -31,18 +31,18 @@ import java.util.HashMap;
import java.util.Iterator;
public class HttpHeader {
// HTTP info
private boolean request = true;
private String type = "GET";
private String url = "/";
private HashMap<String, String> urlAttributes;
private float version = 1.0f;
private int httpCode = 200;
private InputStream in;
// HTTP info
private boolean request = true;
private String type = "GET";
private String url = "/";
private HashMap<String, String> urlAttributes;
private float version = 1.0f;
private int httpCode = 200;
private InputStream in;
// Parameters
private HashMap<String, String> headers;
private HashMap<String, String> cookies;
// Parameters
private HashMap<String, String> headers;
private HashMap<String, String> cookies;
public HttpHeader(){
@ -52,58 +52,58 @@ public class HttpHeader {
}
/**
* @return true if this header represents a server response
*/
public boolean isResponse(){
return !request;
}
/**
* @return true if this header represents a client request
/**
* @return true if this header represents a server response
*/
public boolean isRequest(){
return request;
}
/**
* @return the HTTP message type( ex. GET,POST...)
*/
public String getRequestType(){
return type;
}
/**
* @return the HTTP version of this header
*/
public float getHTTPVersion(){
return version;
}
/**
* @return the HTTP Return Code from a Server
*/
public int getHTTPCode(){
return httpCode;
}
/**
* @return the URL that the client sent the server
*/
public String getRequestURL(){
return url;
}
/**
* @return parses out the page name from the request url and returns it.
public boolean isResponse(){
return !request;
}
/**
* @return true if this header represents a client request
*/
public String getRequestPage() {
if (url != null){
public boolean isRequest(){
return request;
}
/**
* @return the HTTP message type( ex. GET,POST...)
*/
public String getRequestType(){
return type;
}
/**
* @return the HTTP version of this header
*/
public float getHTTPVersion(){
return version;
}
/**
* @return the HTTP Return Code from a Server
*/
public int getHTTPCode(){
return httpCode;
}
/**
* @return the URL that the client sent the server
*/
public String getRequestURL(){
return url;
}
/**
* @return parses out the page name from the request url and returns it.
*/
public String getRequestPage() {
if (url != null){
int start = 0;
if (url.charAt(0) == '/')
start = 1;
int end = url.indexOf('?');
if (end < 0)
int end = url.indexOf('?');
if (end < 0)
end = url.length();
return url.substring(start, end);
}
return null;
}
}
return null;
}
/**
* @return a Iterator with all defined url keys
*/
@ -111,35 +111,35 @@ public class HttpHeader {
return urlAttributes.keySet().iterator();
}
/**
* @return the URL attribute value of the given name. null if there is no such attribute
*/
public String getURLAttribute(String name){
return urlAttributes.get( name );
}
* @return the URL attribute value of the given name. null if there is no such attribute
*/
public String getURLAttribute(String name){
return urlAttributes.get( name );
}
/**
* @return a Iterator with all defined headers
*/
public Iterator<String> getHeaderKeys(){
return headers.keySet().iterator();
}
/**
* @return the HTTP attribute value of the given name. null if there is no such attribute
*/
public String getHeader(String name){
return headers.get( name.toUpperCase() );
}
/**
* @return the HTTP attribute value of the given name. null if there is no such attribute
*/
public String getHeader(String name){
return headers.get( name.toUpperCase() );
}
/**
* @return a Iterator with all defined cookies
*/
public Iterator<String> getCookieKeys(){
return cookies.keySet().iterator();
}
/**
* @return the cookie value of the given name. null if there is no such attribute.
*/
public String getCookie(String name){
return cookies.get( name );
}
/**
* @return the cookie value of the given name. null if there is no such attribute.
*/
public String getCookie(String name){
return cookies.get( name );
}
/**
* @return a Reader that contains the body of the http request.
*/
@ -148,62 +148,62 @@ public class HttpHeader {
}
public void setIsRequest(boolean request) { this.request = request; }
public void setRequestType(String type){
public void setIsRequest(boolean request) { this.request = request; }
public void setRequestType(String type){
this.type = type;
}
public void setHTTPVersion(float version){
public void setHTTPVersion(float version){
this.version = version;
}
public void setHTTPCode(int code){
public void setHTTPCode(int code){
this.httpCode = code;
}
public void setRequestURL(String url){
public void setRequestURL(String url){
this.url = url.trim().replaceAll("//", "/");
}
public void setHeader(String key, String value){
this.headers.put(key.toUpperCase(), value);
}
this.headers.put(key.toUpperCase(), value);
}
protected void setInputStream(InputStream in){
this.in = in;
}
protected HashMap<String,String> getHeaderMap(){
return headers;
}
protected HashMap<String,String> getCookieMap(){
return cookies;
}
protected HashMap<String,String> getUrlAttributeMap(){
return urlAttributes;
}
protected HashMap<String,String> getHeaderMap(){
return headers;
}
protected HashMap<String,String> getCookieMap(){
return cookies;
}
protected HashMap<String,String> getUrlAttributeMap(){
return urlAttributes;
}
public String toString(){
StringBuilder tmp = new StringBuilder();
tmp.append("{Type: ").append(type);
tmp.append(", HTTP_version: HTTP/").append(version);
if(url == null)
tmp.append(", URL: null");
else
tmp.append(", URL: \"").append(url).append('\"');
public String toString(){
StringBuilder tmp = new StringBuilder();
tmp.append("{Type: ").append(type);
tmp.append(", HTTP_version: HTTP/").append(version);
if(url == null)
tmp.append(", URL: null");
else
tmp.append(", URL: \"").append(url).append('\"');
tmp.append(", URL_attr: ").append(toStringAttributes());
tmp.append(", Headers: ").append(toStringHeaders());
tmp.append(", Cookies: ").append(toStringCookies());
tmp.append(", URL_attr: ").append(toStringAttributes());
tmp.append(", Headers: ").append(toStringHeaders());
tmp.append(", Cookies: ").append(toStringCookies());
tmp.append('}');
return tmp.toString();
}
public String toStringHeaders(){
return Converter.toString(headers);
}
public String toStringCookies(){
return Converter.toString(cookies);
}
public String toStringAttributes(){
return Converter.toString(urlAttributes);
}
tmp.append('}');
return tmp.toString();
}
public String toStringHeaders(){
return Converter.toString(headers);
}
public String toStringCookies(){
return Converter.toString(cookies);
}
public String toStringAttributes(){
return Converter.toString(urlAttributes);
}
}

View file

@ -38,33 +38,33 @@ import java.util.regex.Pattern;
public class HttpHeaderParser {
private static final String HEADER_COOKIE = "COOKIE";
private static final Pattern PATTERN_COLON = Pattern.compile(":");
private static final Pattern PATTERN_EQUAL = Pattern.compile("=");
private static final Pattern PATTERN_AND = Pattern.compile("&");
private static final Pattern PATTERN_COLON = Pattern.compile(":");
private static final Pattern PATTERN_EQUAL = Pattern.compile("=");
private static final Pattern PATTERN_AND = Pattern.compile("&");
private InputStream in;
private boolean skipStatusLine;
/**
* Parses the HTTP header information from a stream
*
* @param in is the stream
*/
public HttpHeaderParser(InputStream in){
this.in = in;
/**
* Parses the HTTP header information from a stream
*
* @param in is the stream
*/
public HttpHeaderParser(InputStream in){
this.in = in;
this.skipStatusLine = false;
}
}
/**
* Parses the HTTP header information from a String
*
* @param in is the String
*/
public HttpHeaderParser(String in){
/**
* Parses the HTTP header information from a String
*
* @param in is the String
*/
public HttpHeaderParser(String in){
this(new StringInputStream(in));
}
}
public HttpHeader read() throws IOException {
@ -84,7 +84,7 @@ public class HttpHeaderParser {
}
// Post processing
parseCookieValues(header.getCookieMap(), header.getHeader(HEADER_COOKIE));
parseCookieValues(header.getCookieMap(), header.getHeader(HEADER_COOKIE));
header.setInputStream(in);
return header;
}
@ -96,38 +96,38 @@ public class HttpHeaderParser {
this.skipStatusLine = skipStatusLine;
}
/**
* Parses the first line of a http request/response and stores the values in a HttpHeader object
*
/**
* Parses the first line of a http request/response and stores the values in a HttpHeader object
*
* @param header the header object where the cookies will be stored.
* @param statusLine the status line String
*/
private static void parseStatusLine(HttpHeader header, String statusLine){
// Server Response
if( statusLine.startsWith("HTTP/") ){
header.setIsRequest(false);
header.setHTTPVersion( Float.parseFloat( statusLine.substring( 5 , 8)));
header.setHTTPCode( Integer.parseInt( statusLine.substring( 9, statusLine.indexOf(' ', 9) )));
}
// Client Request
else if(statusLine.contains("HTTP/")){
header.setIsRequest(true);
header.setRequestType( statusLine.substring(0, statusLine.indexOf(" ")).trim() );
header.setHTTPVersion( Float.parseFloat( statusLine.substring(statusLine.lastIndexOf("HTTP/")+5 , statusLine.length()).trim()));
statusLine = (statusLine.substring(header.getRequestType().length()+1, statusLine.lastIndexOf("HTTP/")));
* @param statusLine the status line String
*/
private static void parseStatusLine(HttpHeader header, String statusLine){
// Server Response
if( statusLine.startsWith("HTTP/") ){
header.setIsRequest(false);
header.setHTTPVersion( Float.parseFloat( statusLine.substring( 5 , 8)));
header.setHTTPCode( Integer.parseInt( statusLine.substring( 9, statusLine.indexOf(' ', 9) )));
}
// Client Request
else if(statusLine.contains("HTTP/")){
header.setIsRequest(true);
header.setRequestType( statusLine.substring(0, statusLine.indexOf(" ")).trim() );
header.setHTTPVersion( Float.parseFloat( statusLine.substring(statusLine.lastIndexOf("HTTP/")+5 , statusLine.length()).trim()));
statusLine = (statusLine.substring(header.getRequestType().length()+1, statusLine.lastIndexOf("HTTP/")));
// parse URL and attributes
int index = statusLine.indexOf('?');
if(index > -1){
header.setRequestURL( statusLine.substring(0, index));
statusLine = statusLine.substring( index+1, statusLine.length());
parseURLParameters(header.getUrlAttributeMap(), statusLine);
}
else{
header.setRequestURL(statusLine);
}
}
}
// parse URL and attributes
int index = statusLine.indexOf('?');
if(index > -1){
header.setRequestURL( statusLine.substring(0, index));
statusLine = statusLine.substring( index+1, statusLine.length());
parseURLParameters(header.getUrlAttributeMap(), statusLine);
}
else{
header.setRequestURL(statusLine);
}
}
}
/**
* Parses a http key value paired header line.
@ -144,15 +144,15 @@ public class HttpHeaderParser {
(data.length>1 ? data[1] : "").trim()); //Value
}
/**
* Parses a raw cookie header into key and value pairs
*
* @param map the Map where the cookies will be stored.
* @param cookieValue the raw cookie header value String that will be parsed
*/
public static void parseCookieValues(Map<String,String> map, String cookieValue){
parseHeaderValues(map, cookieValue, ";");
}
/**
* Parses a raw cookie header into key and value pairs
*
* @param map the Map where the cookies will be stored.
* @param cookieValue the raw cookie header value String that will be parsed
*/
public static void parseCookieValues(Map<String,String> map, String cookieValue){
parseHeaderValues(map, cookieValue, ";");
}
/**
@ -173,11 +173,11 @@ public class HttpHeaderParser {
* Parses a header value string that contains key and value paired data and
* stores them in a HashMap. If a pair only contain a key then the value
* will be set as a empty string.
*
* TODO: method is not quote aware
* @param map the Map where key and values will be stored.
*
* TODO: method is not quote aware
* @param map the Map where key and values will be stored.
* @param headerValue the raw header value String that will be parsed.
* @param delimiter the delimiter that separates key and value pairs (e.g. ';' for Cookies or ',' for Cache-Control)
* @param delimiter the delimiter that separates key and value pairs (e.g. ';' for Cookies or ',' for Cache-Control)
*/
public static void parseHeaderValues(Map<String,String> map, String headerValue, String delimiter){
if(headerValue != null && !headerValue.isEmpty()){
@ -192,31 +192,31 @@ public class HttpHeaderParser {
}
/**
* Parses a string with variables from a get or post request that was sent from a client
*
* @param header the header object where the url attributes key and value will be stored.
* @param urlAttributes is the String containing all the attributes
*/
public static void parseURLParameters(HttpHeader header, String urlAttributes){
parseURLParameters(header.getUrlAttributeMap(), urlAttributes);
}
/**
* Parses a string with variables from a get or post request that was sent from a client
*
/**
* Parses a string with variables from a get or post request that was sent from a client
*
* @param header the header object where the url attributes key and value will be stored.
* @param urlAttributes is the String containing all the attributes
*/
public static void parseURLParameters(HttpHeader header, String urlAttributes){
parseURLParameters(header.getUrlAttributeMap(), urlAttributes);
}
/**
* Parses a string with variables from a get or post request that was sent from a client
*
* @param map a map where the url attributes key and value will be stored.
* @param urlAttributes is the String containing all the attributes
*/
public static void parseURLParameters(Map<String,String> map, String urlAttributes){
String[] tmp;
urlAttributes = URLDecoder.decode(urlAttributes);
// get the variables
String[] data = PATTERN_AND.split( urlAttributes );
for(String element : data){
tmp = PATTERN_EQUAL.split(element, 2);
map.put(
tmp[0].trim(), // Key
(tmp.length>1 ? tmp[1] : "").trim()); //Value
}
}
* @param urlAttributes is the String containing all the attributes
*/
public static void parseURLParameters(Map<String,String> map, String urlAttributes){
String[] tmp;
urlAttributes = URLDecoder.decode(urlAttributes);
// get the variables
String[] data = PATTERN_AND.split( urlAttributes );
for(String element : data){
tmp = PATTERN_EQUAL.split(element, 2);
map.put(
tmp[0].trim(), // Key
(tmp.length>1 ? tmp[1] : "").trim()); //Value
}
}
}

View file

@ -34,20 +34,20 @@ import java.util.Map;
*
*/
public interface HttpPage{
/**
* This method has to be implemented for every page.
* This method is called when a client wants a response
* from this specific page.
*
* @param out is a output stream to the client
* @param headers is the header received from the client
/**
* This method has to be implemented for every page.
* This method is called when a client wants a response
* from this specific page.
*
* @param out is a output stream to the client
* @param headers is the header received from the client
* @param session is the session associated with the current client
* @param cookie is cookie information from the client
* @param request is POST and GET requests from the client
* @param cookie is cookie information from the client
* @param request is POST and GET requests from the client
*/
public abstract void respond(HttpPrintStream out,
HttpHeader headers,
Map<String,Object> session,
Map<String,String> cookie,
Map<String,String> request) throws IOException;
public abstract void respond(HttpPrintStream out,
HttpHeader headers,
Map<String,Object> session,
Map<String,String> cookie,
Map<String,String> request) throws IOException;
}

View file

@ -39,73 +39,73 @@ import java.util.HashMap;
*
*/
public class HttpPrintStream extends OutputStream{
// Defines the type of message
public enum HttpMessageType{
REQUEST,
RESPONSE
}
// Defines the type of message
public enum HttpMessageType{
REQUEST,
RESPONSE
}
/** The actual output stream */
private PrintStream out;
/** This defines the supported http version */
private String httpVersion;
/** This defines the type of message that will be generated */
private HttpMessageType message_type;
/** The status code of the message, ONLY for response */
private Integer res_status_code;
/** The request type of the message ONLY for request */
private String req_type;
/** The requesting url ONLY for request */
private String req_url;
/** An Map of all the header values */
private HashMap<String, String> headers;
/** An Map of all the cookies */
private HashMap<String, String> cookies;
/** The buffered header */
private StringBuffer buffer;
/** If the header buffering is enabled */
private boolean buffer_enabled;
/** The actual output stream */
private PrintStream out;
/** This defines the supported http version */
private String httpVersion;
/** This defines the type of message that will be generated */
private HttpMessageType message_type;
/** The status code of the message, ONLY for response */
private Integer res_status_code;
/** The request type of the message ONLY for request */
private String req_type;
/** The requesting url ONLY for request */
private String req_url;
/** An Map of all the header values */
private HashMap<String, String> headers;
/** An Map of all the cookies */
private HashMap<String, String> cookies;
/** The buffered header */
private StringBuffer buffer;
/** If the header buffering is enabled */
private boolean buffer_enabled;
/**
* Creates an new instance of HttpPrintStream with
* message type of RESPONSE and buffering disabled.
*
* @param out is the OutputStream where the data will be written to
*/
public HttpPrintStream(OutputStream out) {
this( out, HttpMessageType.RESPONSE );
}
/**
* Creates an new instance of HttpPrintStream with
* message type buffering disabled.
*
* @param out is the OutputStream where the data will be written to
* @param type is the type of message
*/
public HttpPrintStream(OutputStream out, HttpMessageType type) {
this.out = new PrintStream(out);
/**
* Creates an new instance of HttpPrintStream with
* message type of RESPONSE and buffering disabled.
*
* @param out is the OutputStream where the data will be written to
*/
public HttpPrintStream(OutputStream out) {
this( out, HttpMessageType.RESPONSE );
}
/**
* Creates an new instance of HttpPrintStream with
* message type buffering disabled.
*
* @param out is the OutputStream where the data will be written to
* @param type is the type of message
*/
public HttpPrintStream(OutputStream out, HttpMessageType type) {
this.out = new PrintStream(out);
this.httpVersion = "1.0";
this.message_type = type;
this.res_status_code = 200;
this.headers = new HashMap<String, String>();
this.cookies = new HashMap<String, String>();
this.buffer = new StringBuffer();
this.buffer_enabled = false;
}
this.message_type = type;
this.res_status_code = 200;
this.headers = new HashMap<String, String>();
this.cookies = new HashMap<String, String>();
this.buffer = new StringBuffer();
this.buffer_enabled = false;
}
/**
* Enable the buffering capability of the PrintStream.
* Nothing will be sent to the client when buffering
* is enabled until you close or flush the stream.
* This function will flush the stream if buffering is
* disabled.
*
* @param b
*/
public void enableBuffering(boolean b) throws IOException {
buffer_enabled = b;
if(!buffer_enabled) flush();
}
/**
* Enable the buffering capability of the PrintStream.
* Nothing will be sent to the client when buffering
* is enabled until you close or flush the stream.
* This function will flush the stream if buffering is
* disabled.
*
* @param b
*/
public void enableBuffering(boolean b) throws IOException {
buffer_enabled = b;
if(!buffer_enabled) flush();
}
/**
* Set the http version that will be used in the http header
@ -114,225 +114,225 @@ public class HttpPrintStream extends OutputStream{
this.httpVersion = version;
}
/**
* Adds a cookie that will be sent to the client
*
* @param key is the name of the cookie
* @param value is the value of the cookie
* @throws IOException if the header has already been sent
*/
public void setCookie(String key, String value) throws IOException{
if(cookies == null)
throw new IOException("Header already sent!");
cookies.put(key, value);
}
/**
* Adds a cookie that will be sent to the client
*
* @param key is the name of the cookie
* @param value is the value of the cookie
* @throws IOException if the header has already been sent
*/
public void setCookie(String key, String value) throws IOException{
if(cookies == null)
throw new IOException("Header already sent!");
cookies.put(key, value);
}
/**
* Adds an header value
*
* @param key is the header name
* @param value is the value of the header
* @throws IOException if the header has already been sent
*/
public void setHeader(String key, String value) throws IOException{
if(headers == null)
throw new IOException("Header already sent!");
headers.put(key, value);
}
/**
* Adds an header value
*
* @param key is the header name
* @param value is the value of the header
* @throws IOException if the header has already been sent
*/
public void setHeader(String key, String value) throws IOException{
if(headers == null)
throw new IOException("Header already sent!");
headers.put(key, value);
}
/**
* Sets the status code of the message, ONLY available in HTTP RESPONSE
*
* @param code the code from 100 up to 599
* @throws IOException if the header has already been sent or the message type is wrong
*/
public void setStatusCode(int code) throws IOException{
if( res_status_code == null )
throw new IOException("Header already sent!");
if( message_type != HttpMessageType.RESPONSE )
throw new IOException("Status Code is only available in HTTP RESPONSE!");
res_status_code = code;
}
/**
* Sets the status code of the message, ONLY available in HTTP RESPONSE
*
* @param code the code from 100 up to 599
* @throws IOException if the header has already been sent or the message type is wrong
*/
public void setStatusCode(int code) throws IOException{
if( res_status_code == null )
throw new IOException("Header already sent!");
if( message_type != HttpMessageType.RESPONSE )
throw new IOException("Status Code is only available in HTTP RESPONSE!");
res_status_code = code;
}
/**
* Sets the request type of the message, ONLY available in HTTP REQUEST
*
* @param req_type is the type of the message, e.g. GET, POST...
* @throws IOException if the header has already been sent or the message type is wrong
*/
public void setRequestType(String req_type) throws IOException{
if( req_type == null )
throw new IOException("Header already sent!");
if( message_type != HttpMessageType.REQUEST )
throw new IOException("Request Message Type is only available in HTTP REQUEST!");
this.req_type = req_type;
}
/**
* Sets the requesting URL of the message, ONLY available in HTTP REQUEST
*
* @param req_url is the URL
* @throws IOException if the header has already been sent or the message type is wrong
*/
public void setRequestURL(String req_url) throws IOException{
if( req_url == null )
throw new IOException("Header already sent!");
if( message_type != HttpMessageType.REQUEST )
throw new IOException("Request URL is only available in HTTP REQUEST!");
this.req_url = req_url;
}
/**
* Sets the request type of the message, ONLY available in HTTP REQUEST
*
* @param req_type is the type of the message, e.g. GET, POST...
* @throws IOException if the header has already been sent or the message type is wrong
*/
public void setRequestType(String req_type) throws IOException{
if( req_type == null )
throw new IOException("Header already sent!");
if( message_type != HttpMessageType.REQUEST )
throw new IOException("Request Message Type is only available in HTTP REQUEST!");
this.req_type = req_type;
}
/**
* Sets the requesting URL of the message, ONLY available in HTTP REQUEST
*
* @param req_url is the URL
* @throws IOException if the header has already been sent or the message type is wrong
*/
public void setRequestURL(String req_url) throws IOException{
if( req_url == null )
throw new IOException("Header already sent!");
if( message_type != HttpMessageType.REQUEST )
throw new IOException("Request URL is only available in HTTP REQUEST!");
this.req_url = req_url;
}
protected void setHeaders( HashMap<String,String> map ){
headers = map;
}
protected void setCookies( HashMap<String,String> map ){
cookies = map;
}
protected void setHeaders( HashMap<String,String> map ){
headers = map;
}
protected void setCookies( HashMap<String,String> map ){
cookies = map;
}
/**
* Prints a new line
*/
public void println() throws IOException {
printOrBuffer(System.lineSeparator());
}
/**
* Prints with a new line
*/
public void println(String s) throws IOException {
printOrBuffer(s + System.lineSeparator());
}
/**
* Prints an string
*/
public void print(String s) throws IOException {
printOrBuffer(s);
}
/**
* Prints a new line
*/
public void println() throws IOException {
printOrBuffer(System.lineSeparator());
}
/**
* Prints with a new line
*/
public void println(String s) throws IOException {
printOrBuffer(s + System.lineSeparator());
}
/**
* Prints an string
*/
public void print(String s) throws IOException {
printOrBuffer(s);
}
/**
* Will buffer String or directly output headers if needed and then the String
*/
private void printOrBuffer(String s) throws IOException {
if(buffer_enabled){
buffer.append(s);
}
else{
if(res_status_code != null){
if( message_type==HttpMessageType.REQUEST )
out.print(req_type + " " + req_url + " HTTP/"+httpVersion);
else
out.print("HTTP/"+httpVersion+" " + res_status_code + " " + getStatusString(res_status_code));
out.println();
res_status_code = null;
req_type = null;
req_url = null;
}
if(headers != null){
for(String key : headers.keySet()){
out.println(key + ": " + headers.get(key));
}
headers = null;
}
if(cookies != null){
if( !cookies.isEmpty() ){
if( message_type==HttpMessageType.REQUEST ){
out.print("Cookie: ");
for(String key : cookies.keySet()){
out.print(key + "=" + cookies.get(key) + "; ");
}
out.println();
}
else{
for(String key : cookies.keySet()){
out.print("Set-Cookie: " + key + "=" + cookies.get(key) + ";");
out.println();
}
}
}
out.println();
cookies = null;
}
out.print(s);
}
}
/**
* Will buffer String or directly output headers if needed and then the String
*/
private void printOrBuffer(String s) throws IOException {
if(buffer_enabled){
buffer.append(s);
}
else{
if(res_status_code != null){
if( message_type==HttpMessageType.REQUEST )
out.print(req_type + " " + req_url + " HTTP/"+httpVersion);
else
out.print("HTTP/"+httpVersion+" " + res_status_code + " " + getStatusString(res_status_code));
out.println();
res_status_code = null;
req_type = null;
req_url = null;
}
if(headers != null){
for(String key : headers.keySet()){
out.println(key + ": " + headers.get(key));
}
headers = null;
}
if(cookies != null){
if( !cookies.isEmpty() ){
if( message_type==HttpMessageType.REQUEST ){
out.print("Cookie: ");
for(String key : cookies.keySet()){
out.print(key + "=" + cookies.get(key) + "; ");
}
out.println();
}
else{
for(String key : cookies.keySet()){
out.print("Set-Cookie: " + key + "=" + cookies.get(key) + ";");
out.println();
}
}
}
out.println();
cookies = null;
}
out.print(s);
}
}
/**
* @return if headers has been sent. The setHeader, setStatusCode, setCookie method will throw Exceptions
*/
public boolean isHeaderSent() {
return res_status_code == null && headers == null && cookies == null;
}
/**
* @return if headers has been sent. The setHeader, setStatusCode, setCookie method will throw Exceptions
*/
public boolean isHeaderSent() {
return res_status_code == null && headers == null && cookies == null;
}
/**
* Sends out the buffer and clears it
*/
@Override
public void flush() throws IOException {
flushBuffer();
out.flush();
}
/**
* Sends out the buffer and clears it
*/
@Override
public void flush() throws IOException {
flushBuffer();
out.flush();
}
@Override
public void close() throws IOException {
flush();
out.close();
}
@Override
public void close() throws IOException {
flush();
out.close();
}
protected void flushBuffer() throws IOException {
if(buffer_enabled){
buffer_enabled = false;
printOrBuffer(buffer.toString());
buffer.delete(0, buffer.length());
buffer_enabled = true;
}
else if(res_status_code != null || headers != null || cookies != null){
printOrBuffer("");
}
}
protected void flushBuffer() throws IOException {
if(buffer_enabled){
buffer_enabled = false;
printOrBuffer(buffer.toString());
buffer.delete(0, buffer.length());
buffer_enabled = true;
}
else if(res_status_code != null || headers != null || cookies != null){
printOrBuffer("");
}
}
/**
* Will flush all buffers and write binary data to stream
*/
@Override
public void write(int b) throws IOException {
flushBuffer();
out.write(b);
}
/**
* * Will flush all buffers and write binary data to stream
*/
@Override
public void write(byte[] buf, int off, int len) throws IOException {
flushBuffer();
out.write(buf, off, len);
}
/**
* Will flush all buffers and write binary data to stream
*/
@Override
public void write(int b) throws IOException {
flushBuffer();
out.write(b);
}
/**
* * Will flush all buffers and write binary data to stream
*/
@Override
public void write(byte[] buf, int off, int len) throws IOException {
flushBuffer();
out.write(buf, off, len);
}
private String getStatusString(int type){
switch(type){
case 100: return "Continue";
case 200: return "OK";
case 301: return "Moved Permanently";
case 304: return "Not Modified";
case 307: return "Temporary Redirect";
case 400: return "Bad Request";
case 401: return "Unauthorized";
case 403: return "Forbidden";
case 404: return "Not Found";
case 500: return "Internal Server Error";
case 501: return "Not Implemented";
default: return "";
}
}
private String getStatusString(int type){
switch(type){
case 100: return "Continue";
case 200: return "OK";
case 301: return "Moved Permanently";
case 304: return "Not Modified";
case 307: return "Temporary Redirect";
case 400: return "Bad Request";
case 401: return "Unauthorized";
case 403: return "Forbidden";
case 404: return "Not Found";
case 500: return "Internal Server Error";
case 501: return "Not Implemented";
default: return "";
}
}
public String toString() {
public String toString() {
StringBuilder str = new StringBuilder();
str.append("{http_type: ").append(message_type);
if (res_status_code != null) {
if (message_type == HttpMessageType.REQUEST) {
str.append(", req_type: ").append(req_type);
if(req_url == null)
if(req_url == null)
str.append(", req_url: null");
else
else
str.append(", req_url: \"").append(req_url).append('\"');
} else if (message_type == HttpMessageType.RESPONSE){
str.append(", status_code: ").append(res_status_code);

View file

@ -50,122 +50,122 @@ import java.util.logging.Logger;
* @author Ziver
*/
public class HttpServer extends ThreadedTCPNetworkServer{
private static final Logger logger = LogUtil.getLogger();
private static final Logger logger = LogUtil.getLogger();
public static final String SESSION_KEY_ID = "session_id";
public static final String SESSION_KEY_TTL = "session_ttl";
public static final String SERVER_NAME = "Zutil HttpServer";
public static final int SESSION_TTL = 10*60*1000; // in milliseconds
public static final String SESSION_KEY_ID = "session_id";
public static final String SESSION_KEY_TTL = "session_ttl";
public static final String SERVER_NAME = "Zutil HttpServer";
public static final int SESSION_TTL = 10*60*1000; // in milliseconds
private Map<String,HttpPage> pages;
private HttpPage defaultPage;
private Map<String,Map<String,Object>> sessions;
private int nextSessionId;
private Map<String,HttpPage> pages;
private HttpPage defaultPage;
private Map<String,Map<String,Object>> sessions;
private int nextSessionId;
/**
* Creates a new instance of the sever
*
* @param port The port that the server should listen to
*/
public HttpServer(int port){
this(port, null, null);
}
/**
* Creates a new instance of the sever
*
* @param port The port that the server should listen to
*/
public HttpServer(int port){
this(port, null, null);
}
/**
* Creates a new instance of the sever
*
* @param port The port that the server should listen to
* @param keyStore If this is not null then the server will use SSL connection with this keyStore file path
* @param keyStorePass If this is not null then the server will use a SSL connection with the given certificate
*/
public HttpServer(int port, File keyStore, String keyStorePass){
super( port, keyStore, keyStorePass );
/**
* Creates a new instance of the sever
*
* @param port The port that the server should listen to
* @param keyStore If this is not null then the server will use SSL connection with this keyStore file path
* @param keyStorePass If this is not null then the server will use a SSL connection with the given certificate
*/
public HttpServer(int port, File keyStore, String keyStorePass){
super( port, keyStore, keyStorePass );
pages = new ConcurrentHashMap<>();
sessions = new ConcurrentHashMap<>();
nextSessionId = 0;
pages = new ConcurrentHashMap<>();
sessions = new ConcurrentHashMap<>();
nextSessionId = 0;
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleWithFixedDelay(new SessionGarbageCollector(), 10000, SESSION_TTL / 2, TimeUnit.MILLISECONDS);
exec.scheduleWithFixedDelay(new SessionGarbageCollector(), 10000, SESSION_TTL / 2, TimeUnit.MILLISECONDS);
logger.info("HTTP"+(keyStore==null?"":"S")+" Server ready!");
}
logger.info("HTTP"+(keyStore==null?"":"S")+" Server ready!");
}
/**
* This class acts as an garbage collector that
* removes old sessions from the session HashMap
*/
private class SessionGarbageCollector implements Runnable {
public void run(){
Object[] keys = sessions.keySet().toArray();
int count = 0;
for(Object key : keys){
Map<String,Object> session = sessions.get(key);
/**
* This class acts as an garbage collector that
* removes old sessions from the session HashMap
*/
private class SessionGarbageCollector implements Runnable {
public void run(){
Object[] keys = sessions.keySet().toArray();
int count = 0;
for(Object key : keys){
Map<String,Object> session = sessions.get(key);
// Check if session is still valid
if(((Timer) session.get(SESSION_KEY_TTL)).hasTimedOut()){
sessions.remove(key);
++count;
}
}
if (count > 0)
logger.fine("Removed "+count+" old sessions");
}
}
// Check if session is still valid
if(((Timer) session.get(SESSION_KEY_TTL)).hasTimedOut()){
sessions.remove(key);
++count;
}
}
if (count > 0)
logger.fine("Removed "+count+" old sessions");
}
}
/**
* Add a HttpPage to a specific URL
*
* @param name The URL or name of the page
* @param page The page itself
*/
public void setPage(String name, HttpPage page){
if(name.charAt(0) != '/')
name = "/"+name;
pages.put(name, page);
}
/**
* Add a HttpPage to a specific URL
*
* @param name The URL or name of the page
* @param page The page itself
*/
public void setPage(String name, HttpPage page){
if(name.charAt(0) != '/')
name = "/"+name;
pages.put(name, page);
}
/**
* This is a default page that will be shown
* if there is no other matching page,
*
* @param page The HttpPage that will be shown
*/
public void setDefaultPage(HttpPage page){
defaultPage = page;
}
/**
* This is a default page that will be shown
* if there is no other matching page,
*
* @param page The HttpPage that will be shown
*/
public void setDefaultPage(HttpPage page){
defaultPage = page;
}
protected ThreadedTCPNetworkServerThread getThreadInstance( Socket s ){
try {
return new HttpServerThread( s );
} catch (IOException e) {
logger.log(Level.SEVERE, "Could not start new Thread", e);
}
return null;
}
protected ThreadedTCPNetworkServerThread getThreadInstance( Socket s ){
try {
return new HttpServerThread( s );
} catch (IOException e) {
logger.log(Level.SEVERE, "Could not start new Thread", e);
}
return null;
}
/**
* Internal class that handles all the requests
*/
protected class HttpServerThread implements ThreadedTCPNetworkServerThread{
private HttpPrintStream out;
private BufferedInputStream in;
private Socket socket;
/**
* Internal class that handles all the requests
*/
protected class HttpServerThread implements ThreadedTCPNetworkServerThread{
private HttpPrintStream out;
private BufferedInputStream in;
private Socket socket;
public HttpServerThread(Socket socket) throws IOException{
out = new HttpPrintStream(socket.getOutputStream());
in = new BufferedInputStream(socket.getInputStream());
this.socket = socket;
}
public HttpServerThread(Socket socket) throws IOException{
out = new HttpPrintStream(socket.getOutputStream());
in = new BufferedInputStream(socket.getInputStream());
this.socket = socket;
}
public void run(){
public void run(){
long time = System.currentTimeMillis();
HttpHeaderParser headerParser;
HttpHeader header = null;
Map<String, Object> session = null;
try {
try {
//**************************** PARSE REQUEST *********************************
headerParser = new HttpHeaderParser(in);
header = headerParser.read();
@ -176,8 +176,8 @@ public class HttpServer extends ThreadedTCPNetworkServer{
//******* Read in the post data if available
if (header.getHeader("Content-Length") != null &&
header.getHeader("Content-Type") != null &&
header.getHeader("Content-Type").contains("application/x-www-form-urlencoded")) {
header.getHeader("Content-Type") != null &&
header.getHeader("Content-Type").contains("application/x-www-form-urlencoded")) {
// Reads the post data size
int postDataLength = Integer.parseInt(header.getHeader("Content-Length"));
// read the data
@ -186,8 +186,8 @@ public class HttpServer extends ThreadedTCPNetworkServer{
for (int i = 0; i < postDataLength; i++) {
tmpBuff.append((char) in.read());
}
// get the variables
HttpHeaderParser.parseURLParameters(header, tmpBuff.toString());
// get the variables
HttpHeaderParser.parseURLParameters(header, tmpBuff.toString());
}
//**************************** HANDLE REQUEST *********************************
@ -228,25 +228,25 @@ public class HttpServer extends ThreadedTCPNetworkServer{
out.setStatusCode(404);
out.println("404 Page Not Found: " + header.getRequestURL());
logger.warning("Page not defined: " + header.getRequestURL());
}
//********************************************************************************
} catch (Exception e) {
logRequest(header, session, time);
logger.log(Level.SEVERE, "500 Internal Server Error", e);
try {
if (!out.isHeaderSent())
out.setStatusCode(500);
if (e.getMessage() != null)
out.println("500 Internal Server Error: " + e.getMessage());
else if (e.getCause() != null) {
out.println("500 Internal Server Error: " + e.getCause().getMessage());
} else {
out.println("500 Internal Server Error: " + e);
}
}catch(IOException ioe){
logger.log(Level.SEVERE, null, ioe);
}
}
}
//********************************************************************************
} catch (Exception e) {
logRequest(header, session, time);
logger.log(Level.SEVERE, "500 Internal Server Error", e);
try {
if (!out.isHeaderSent())
out.setStatusCode(500);
if (e.getMessage() != null)
out.println("500 Internal Server Error: " + e.getMessage());
else if (e.getCause() != null) {
out.println("500 Internal Server Error: " + e.getCause().getMessage());
} else {
out.println("500 Internal Server Error: " + e);
}
}catch(IOException ioe){
logger.log(Level.SEVERE, null, ioe);
}
}
finally {
try{
out.close();
@ -256,8 +256,8 @@ public class HttpServer extends ThreadedTCPNetworkServer{
logger.log(Level.WARNING, "Could not close connection", e);
}
}
}
}
}
}
protected static void logRequest(HttpHeader header,

View file

@ -33,130 +33,130 @@ import java.util.HashMap;
* @author Ziver
*/
public class HttpURL {
public static final String PROTOCOL_SEPARATOR = "://";
public static final String PORT_SEPARATOR = ":";
public static final String PATH_SEPARATOR = "/";
public static final String PARAMETER_SEPARATOR = "?";
public static final String ANCHOR_SEPARATOR = "#";
public static final String PROTOCOL_SEPARATOR = "://";
public static final String PORT_SEPARATOR = ":";
public static final String PATH_SEPARATOR = "/";
public static final String PARAMETER_SEPARATOR = "?";
public static final String ANCHOR_SEPARATOR = "#";
private String protocol = "";
private String host = "127.0.0.1";
private int port = -1;
private String path;
private String anchor;
private HashMap<String,String> parameters = new HashMap<String,String>();
private String protocol = "";
private String host = "127.0.0.1";
private int port = -1;
private String path;
private String anchor;
public HttpURL(){}
public HttpURL( URL url ){
this.setProtocol( url.getProtocol() );
this.setHost( url.getHost() );
this.setPort( url.getPort() );
this.setPath( url.getPath() );
}
public String getProtocol( ){
return protocol;
}
public String getHost( ){
return host;
}
public int getPort( ){
return port;
}
public String getPath( ){
return path;
}
public String getAnchor( ){
return anchor;
}
public void setProtocol( String prot ){
this.protocol = prot;
}
public void setHost( String host ){
this.host = host;
}
public void setPort( int port ){
this.port = port;
}
public void setPath( String path ){
if( path.length() >= 1 && !path.startsWith(PATH_SEPARATOR))
path = PATH_SEPARATOR + path;
this.path = path;
}
public void setAnchor( String anch ){
this.anchor = anch;
}
public void setParameter( String key, String value ){
this.parameters.put(key, value);
}
protected void setParameters( HashMap<String,String> pars ){
this.parameters = pars;
}
/**
* Generates the parameter string in a URL.
*
* e.g.
* "key=value&key2=value&..."
*/
public String getParameterString(){
StringBuilder param = new StringBuilder();
for(String key : parameters.keySet()){
if (param.length() > 0)
param.append('&');
param.append(key);
param.append('=');
param.append( parameters.get(key) );
}
return param.toString();
}
private HashMap<String,String> parameters = new HashMap<String,String>();
/**
* Generates a path that are used in the HTTP header
*/
public String getHttpURL(){
StringBuilder url = new StringBuilder();
url.append( path );
if( !parameters.isEmpty() )
url.append( PARAMETER_SEPARATOR ).append( getParameterString() );
return url.toString();
}
/**
* Generates a full URL
*/
public String getURL(){
return toString();
}
/**
* Generates the whole URL
*/
public String toString(){
StringBuilder url = new StringBuilder();
url.append( protocol );
url.append( PROTOCOL_SEPARATOR );
url.append( host );
if( port > 0 )
url.append( PORT_SEPARATOR ).append( port );
if( path != null )
url.append( path );
else
url.append( PATH_SEPARATOR );
if( !parameters.isEmpty() )
url.append( PARAMETER_SEPARATOR ).append( getParameterString() );
if( anchor != null )
url.append( ANCHOR_SEPARATOR ).append( anchor );
return url.toString();
}
public HttpURL(){}
public HttpURL( URL url ){
this.setProtocol( url.getProtocol() );
this.setHost( url.getHost() );
this.setPort( url.getPort() );
this.setPath( url.getPath() );
}
public String getProtocol( ){
return protocol;
}
public String getHost( ){
return host;
}
public int getPort( ){
return port;
}
public String getPath( ){
return path;
}
public String getAnchor( ){
return anchor;
}
public void setProtocol( String prot ){
this.protocol = prot;
}
public void setHost( String host ){
this.host = host;
}
public void setPort( int port ){
this.port = port;
}
public void setPath( String path ){
if( path.length() >= 1 && !path.startsWith(PATH_SEPARATOR))
path = PATH_SEPARATOR + path;
this.path = path;
}
public void setAnchor( String anch ){
this.anchor = anch;
}
public void setParameter( String key, String value ){
this.parameters.put(key, value);
}
protected void setParameters( HashMap<String,String> pars ){
this.parameters = pars;
}
/**
* Generates the parameter string in a URL.
*
* e.g.
* "key=value&key2=value&..."
*/
public String getParameterString(){
StringBuilder param = new StringBuilder();
for(String key : parameters.keySet()){
if (param.length() > 0)
param.append('&');
param.append(key);
param.append('=');
param.append( parameters.get(key) );
}
return param.toString();
}
/**
* Generates a path that are used in the HTTP header
*/
public String getHttpURL(){
StringBuilder url = new StringBuilder();
url.append( path );
if( !parameters.isEmpty() )
url.append( PARAMETER_SEPARATOR ).append( getParameterString() );
return url.toString();
}
/**
* Generates a full URL
*/
public String getURL(){
return toString();
}
/**
* Generates the whole URL
*/
public String toString(){
StringBuilder url = new StringBuilder();
url.append( protocol );
url.append( PROTOCOL_SEPARATOR );
url.append( host );
if( port > 0 )
url.append( PORT_SEPARATOR ).append( port );
if( path != null )
url.append( path );
else
url.append( PATH_SEPARATOR );
if( !parameters.isEmpty() )
url.append( PARAMETER_SEPARATOR ).append( getParameterString() );
if( anchor != null )
url.append( ANCHOR_SEPARATOR ).append( anchor );
return url.toString();
}
}

View file

@ -31,14 +31,14 @@ package zutil.net.http.multipart;
* @author Ziver
*/
public interface MultipartField{
/**
* @return the amount of data received for this field. Might only be available when all data has been processed
*/
public long getLength();
/**
* @return the name of the field.
*/
public String getName();
/**
* @return the amount of data received for this field. Might only be available when all data has been processed
*/
public long getLength();
/**
* @return the name of the field.
*/
public String getName();
}

View file

@ -42,26 +42,26 @@ import static zutil.net.http.multipart.MultipartParser.HEADER_CONTENT_TYPE;
public class MultipartFileField implements MultipartField{
private static final Logger logger = LogUtil.getLogger();
private String fieldname;
private String filename;
private String fieldname;
private String filename;
private String contentType;
private byte[] content;
private InputStream in;
protected MultipartFileField(Map<String,String> headers, InputStream in) throws IOException {
this.fieldname = headers.get("name");
this.filename = headers.get("filename");
this.contentType = headers.get(HEADER_CONTENT_TYPE);
protected MultipartFileField(Map<String,String> headers, InputStream in) throws IOException {
this.fieldname = headers.get("name");
this.filename = headers.get("filename");
this.contentType = headers.get(HEADER_CONTENT_TYPE);
this.in = in;
}
/**
* @return the amount of data received for this field
*/
public long getLength(){
return 0; //TODO:
}
}
/**
* @return the amount of data received for this field
*/
public long getLength(){
return 0; //TODO:
}
/**
* @return the field name
@ -70,13 +70,13 @@ public class MultipartFileField implements MultipartField{
return fieldname;
}
public String getFilename(){
return filename;
}
public String getFilename(){
return filename;
}
public String getContentType() {
return contentType;
}
public String getContentType() {
return contentType;
}
@ -100,20 +100,20 @@ public class MultipartFileField implements MultipartField{
}
/**
* Reads in all data and save it into the specified file.
* Reads in all data and save it into the specified file.
*
* Note: Only one of the methods {@link #getContent()} or
* {@link #saveToFile(File)} can be used as they will consume the data in the stream.
*
* @param file is the new file where the data will be stored
*/
public void saveToFile(File file) throws IOException {
if (in == null)
throw new IOException("Stream already consumed.");
*
* @param file is the new file where the data will be stored
*/
public void saveToFile(File file) throws IOException {
if (in == null)
throw new IOException("Stream already consumed.");
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
IOUtil.copyStream(in, out);
out.close();
in = null; // reset InputStream
}
}
}

View file

@ -51,12 +51,12 @@ public class MultipartParser implements Iterable<MultipartField>{
protected static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition".toUpperCase();
protected static final String HEADER_CONTENT_TYPE = "Content-Type".toUpperCase();
/** This is the delimiter that will separate the fields */
private String delimiter;
/** The length of the HTTP Body */
private long contentLength;
/** This is the input stream */
private InputStream in;
/** This is the delimiter that will separate the fields */
private String delimiter;
/** The length of the HTTP Body */
private long contentLength;
/** This is the input stream */
private InputStream in;
private MultiPartIterator iterator;
@ -66,11 +66,11 @@ public class MultipartParser implements Iterable<MultipartField>{
this.delimiter = delimiter;
this.contentLength = length;
}
public MultipartParser(HttpHeader header){
this(header.getInputStream(),
public MultipartParser(HttpHeader header){
this(header.getInputStream(),
parseDelimiter(header.getHeader("Content-type")),
Long.parseLong(header.getHeader("Content-Length")));
}
}
private static String parseDelimiter(String contentTypeHeader){
String delimiter = contentTypeHeader.split(" *; *")[1];
@ -78,18 +78,18 @@ public class MultipartParser implements Iterable<MultipartField>{
return delimiter;
}
public long getContentLength(){
return contentLength;
}
public long getContentLength(){
return contentLength;
}
@Override
public Iterator<MultipartField> iterator() {
@Override
public Iterator<MultipartField> iterator() {
if (iterator == null)
iterator = new MultiPartIterator();
return iterator;
}
return iterator;
}
protected class MultiPartIterator implements Iterator<MultipartField>{

View file

@ -35,43 +35,43 @@ import java.nio.channels.spi.SelectorProvider;
public class NioClient extends NioNetwork{
private InetSocketAddress remoteAddress;
/**
* Creates a NioClient that connects to a server
*
* @param remoteAddress the server address
* @param remotePort the port to listen on
*/
public NioClient(InetAddress remoteAddress, int remotePort) throws IOException {
this.remoteAddress = new InetSocketAddress(remoteAddress, remotePort);
connect(this.remoteAddress);
}
private InetSocketAddress remoteAddress;
protected Selector initSelector() throws IOException {
// Create a new selector
return SelectorProvider.provider().openSelector();
}
/**
* Sends a Message to the connected server
*
* @param data the data to be sent
*/
public void send(Message data) throws IOException {
send(remoteAddress, data);
}
/**
* Creates a NioClient that connects to a server
*
* @param remoteAddress the server address
* @param remotePort the port to listen on
*/
public NioClient(InetAddress remoteAddress, int remotePort) throws IOException {
this.remoteAddress = new InetSocketAddress(remoteAddress, remotePort);
connect(this.remoteAddress);
}
/**
* Sends a Message to the connected server
*
* @param data the data to be sent
*/
public void send(byte[] data) throws IOException {
send(remoteAddress, data);
}
protected Selector initSelector() throws IOException {
// Create a new selector
return SelectorProvider.provider().openSelector();
}
public SocketAddress getRemoteAddress(){
return remoteAddress;
/**
* Sends a Message to the connected server
*
* @param data the data to be sent
*/
public void send(Message data) throws IOException {
send(remoteAddress, data);
}
/**
* Sends a Message to the connected server
*
* @param data the data to be sent
*/
public void send(byte[] data) throws IOException {
send(remoteAddress, data);
}
public SocketAddress getRemoteAddress(){
return remoteAddress;
}
}

View file

@ -43,33 +43,33 @@ import java.util.logging.Logger;
public abstract class NioNetwork implements Runnable {
private static Logger logger = LogUtil.getLogger();
private static Logger logger = LogUtil.getLogger();
protected SocketAddress localAddress;
// The channel on which we'll accept connections
protected ServerSocketChannel serverChannel;
// The selector we will be monitoring
private Selector selector;
// The buffer into which we'll read data when it's available
private ByteBuffer readBuffer = ByteBuffer.allocate(8192);
protected Worker worker;
protected SocketAddress localAddress;
// The channel on which we'll accept connections
protected ServerSocketChannel serverChannel;
// The selector we will be monitoring
private Selector selector;
// The buffer into which we'll read data when it's available
private ByteBuffer readBuffer = ByteBuffer.allocate(8192);
protected Worker worker;
// This map contains all the clients that are connected
protected Map<InetSocketAddress, ClientData> clients = new HashMap<InetSocketAddress, ClientData>();
// This map contains all the clients that are connected
protected Map<InetSocketAddress, ClientData> clients = new HashMap<InetSocketAddress, ClientData>();
// A list of PendingChange instances
private List<ChangeRequest> pendingChanges = new LinkedList<ChangeRequest>();
// Maps a SocketChannel to a list of ByteBuffer instances
private Map<SocketChannel, List<ByteBuffer>> pendingWriteData = new HashMap<SocketChannel, List<ByteBuffer>>();
// A list of PendingChange instances
private List<ChangeRequest> pendingChanges = new LinkedList<ChangeRequest>();
// Maps a SocketChannel to a list of ByteBuffer instances
private Map<SocketChannel, List<ByteBuffer>> pendingWriteData = new HashMap<SocketChannel, List<ByteBuffer>>();
/**
* Create a client based Network object
*/
public NioNetwork() throws IOException {
this(null);
}
/**
* Create a client based Network object
*/
public NioNetwork() throws IOException {
this(null);
}
/**
* Create a server based Network object
@ -77,25 +77,25 @@ public abstract class NioNetwork implements Runnable {
* @param localAddress the address the server will listen on
*/
public NioNetwork(SocketAddress localAddress) throws IOException {
this.localAddress = localAddress;
// init selector
this.localAddress = localAddress;
// init selector
this.selector = initSelector();
// init traffic thread
new Thread(this).start();
}
protected abstract Selector initSelector() throws IOException;
protected abstract Selector initSelector() throws IOException;
/**
* Sets the default worker for non System messages.
*
* @param worker the worker that should handle incoming messages
*/
public void setDefaultWorker(Worker worker){
this.worker = worker;
}
/**
* Sets the default worker for non System messages.
*
* @param worker the worker that should handle incoming messages
*/
public void setDefaultWorker(Worker worker){
this.worker = worker;
}
/**
@ -118,9 +118,9 @@ public abstract class NioNetwork implements Runnable {
}
public void send(SocketAddress address, Object data) throws IOException{
send(address, Converter.toBytes(data));
}
public void send(SocketAddress address, Object data) throws IOException{
send(address, Converter.toBytes(data));
}
/**
* Queues a message to be sent
@ -128,61 +128,61 @@ public abstract class NioNetwork implements Runnable {
* @param address the target address where the message should be sent
* @param data the data to send
*/
public void send(SocketAddress address, byte[] data){
public void send(SocketAddress address, byte[] data){
logger.finest("Sending Queue...");
SocketChannel socket = getSocketChannel(address);
SocketChannel socket = getSocketChannel(address);
// And queue the data we want written
synchronized (pendingWriteData) {
List<ByteBuffer> queue = pendingWriteData.get(socket);
if (queue == null) {
queue = new ArrayList<>();
pendingWriteData.put(socket, queue);
}
queue.add(ByteBuffer.wrap(data));
}
// Changing the key state to write
synchronized (pendingChanges) {
// Indicate we want the interest ops set changed
pendingChanges.add(new ChangeRequest(socket, ChangeRequest.CHANGEOPS, SelectionKey.OP_WRITE));
}
// Finally, wake up our selecting thread so it can make the required changes
selector.wakeup();
}
// And queue the data we want written
synchronized (pendingWriteData) {
List<ByteBuffer> queue = pendingWriteData.get(socket);
if (queue == null) {
queue = new ArrayList<>();
pendingWriteData.put(socket, queue);
}
queue.add(ByteBuffer.wrap(data));
}
// Changing the key state to write
synchronized (pendingChanges) {
// Indicate we want the interest ops set changed
pendingChanges.add(new ChangeRequest(socket, ChangeRequest.CHANGEOPS, SelectionKey.OP_WRITE));
}
// Finally, wake up our selecting thread so it can make the required changes
selector.wakeup();
}
public void run() {
logger.info("NioNetwork Started.");
while (selector.isOpen()) {
try {
// Handle any pending changes
synchronized (pendingChanges) {
Iterator<ChangeRequest> changes = pendingChanges.iterator();
while (changes.hasNext()) {
ChangeRequest change = changes.next();
switch (change.type) {
case ChangeRequest.CHANGEOPS:
SelectionKey key = change.socket.keyFor(selector);
key.interestOps(change.ops);
logger.finest("change.ops "+change.ops);
break;
case ChangeRequest.REGISTER:
change.socket.register(selector, change.ops);
logger.finest("register socket ");
break;
}
}
pendingChanges.clear();
}
public void run() {
logger.info("NioNetwork Started.");
while (selector.isOpen()) {
try {
// Handle any pending changes
synchronized (pendingChanges) {
Iterator<ChangeRequest> changes = pendingChanges.iterator();
while (changes.hasNext()) {
ChangeRequest change = changes.next();
switch (change.type) {
case ChangeRequest.CHANGEOPS:
SelectionKey key = change.socket.keyFor(selector);
key.interestOps(change.ops);
logger.finest("change.ops "+change.ops);
break;
case ChangeRequest.REGISTER:
change.socket.register(selector, change.ops);
logger.finest("register socket ");
break;
}
}
pendingChanges.clear();
}
// Wait for an event from one of the channels
selector.select();
logger.finest("selector is awake");
// Wait for an event from one of the channels
selector.select();
logger.finest("selector is awake");
// Iterate over the set of keys for which events are available
// Iterate over the set of keys for which events are available
if (selector.isOpen()) {
Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator();
while (selectedKeys.hasNext()) {
@ -208,33 +208,33 @@ public abstract class NioNetwork implements Runnable {
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
logger.info("Shutting down NioNetwork");
}
} catch (Exception e) {
e.printStackTrace();
}
}
logger.info("Shutting down NioNetwork");
}
/**
* Handle an accept event from a remote host. Channel can only be a server socket.
*/
private void accept(SelectionKey key) throws IOException {
// For an accept to be pending the channel must be a server socket channel.
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
/**
* Handle an accept event from a remote host. Channel can only be a server socket.
*/
private void accept(SelectionKey key) throws IOException {
// For an accept to be pending the channel must be a server socket channel.
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
// Accept the connection and make it non-blocking
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.socket().setReuseAddress(true);
socketChannel.configureBlocking(false);
// Accept the connection and make it non-blocking
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.socket().setReuseAddress(true);
socketChannel.configureBlocking(false);
// Register the new SocketChannel with our Selector, indicating
// we'd like to be notified when there's data waiting to be read
socketChannel.register(selector, SelectionKey.OP_READ);
// Register the new SocketChannel with our Selector, indicating
// we'd like to be notified when there's data waiting to be read
socketChannel.register(selector, SelectionKey.OP_READ);
// adds the client to the clients list
// adds the client to the clients list
registerSocketChannel(socketChannel);
logger.fine("New Connection("+socketChannel.getRemoteAddress()+")!!! Count: "+clients.size());
}
}
/**
* Finnish an ongoing remote connection establishment procedure
@ -291,47 +291,47 @@ public abstract class NioNetwork implements Runnable {
}
}
/**
* Handle a read event from a socket specified by the key.
*/
private void read(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
SocketAddress remoteAdr = socketChannel.socket().getRemoteSocketAddress();
/**
* Handle a read event from a socket specified by the key.
*/
private void read(SelectionKey key) throws IOException {
SocketChannel socketChannel = (SocketChannel) key.channel();
SocketAddress remoteAdr = socketChannel.socket().getRemoteSocketAddress();
// Clear out our read buffer so it's ready for new data
readBuffer.clear();
// Clear out our read buffer so it's ready for new data
readBuffer.clear();
// Attempt to read off the channel
int numRead;
try {
numRead = socketChannel.read(readBuffer);
} catch (IOException e) {
// The remote forcibly closed the connection, cancel
// the selection key and close the channel.
key.cancel();
socketChannel.close();
clients.remove(remoteAdr);
pendingWriteData.remove(socketChannel);
logger.fine("Connection forcibly closed("+remoteAdr+")! Remaining connections: "+clients.size());
throw new IOException("Remote forcibly closed the connection");
}
// Attempt to read off the channel
int numRead;
try {
numRead = socketChannel.read(readBuffer);
} catch (IOException e) {
// The remote forcibly closed the connection, cancel
// the selection key and close the channel.
key.cancel();
socketChannel.close();
clients.remove(remoteAdr);
pendingWriteData.remove(socketChannel);
logger.fine("Connection forcibly closed("+remoteAdr+")! Remaining connections: "+clients.size());
throw new IOException("Remote forcibly closed the connection");
}
if (numRead == -1) {
// Remote entity shut the socket down cleanly. Do the
// same from our end and cancel the channel.
key.channel().close();
key.cancel();
clients.remove(remoteAdr);
pendingWriteData.remove(socketChannel);
logger.fine("Connection Closed("+remoteAdr+")! Remaining connections: "+clients.size());
if (numRead == -1) {
// Remote entity shut the socket down cleanly. Do the
// same from our end and cancel the channel.
key.channel().close();
key.cancel();
clients.remove(remoteAdr);
pendingWriteData.remove(socketChannel);
logger.fine("Connection Closed("+remoteAdr+")! Remaining connections: "+clients.size());
throw new IOException("Remote closed the connection");
}
}
// Make a correctly sized copy of the data before handing it to the client
//byte[] rspByteData = new byte[numRead];
//System.arraycopy(readBuffer.array(), 0, rspByteData, 0, numRead);
// Make a correctly sized copy of the data before handing it to the client
//byte[] rspByteData = new byte[numRead];
//System.arraycopy(readBuffer.array(), 0, rspByteData, 0, numRead);
try{
try{
Object rspData = Converter.toObject(readBuffer.array());
// Hand the data off to our worker thread
@ -341,10 +341,10 @@ public abstract class NioNetwork implements Runnable {
} else {
logger.fine("No worker set, message unhandled!");
}
}catch(Exception e){
e.printStackTrace();
}
}
}catch(Exception e){
e.printStackTrace();
}
}
@ -370,22 +370,22 @@ public abstract class NioNetwork implements Runnable {
closeConnection(getSocketChannel(address));
}
private void closeConnection(SocketChannel socketChannel) throws IOException{
socketChannel.close();
socketChannel.keyFor(selector).cancel();
}
private void closeConnection(SocketChannel socketChannel) throws IOException{
socketChannel.close();
socketChannel.keyFor(selector).cancel();
}
/**
* Close all connections
*/
public void close() throws IOException{
if(serverChannel != null){
serverChannel.close();
serverChannel.keyFor(selector).cancel();
}
public void close() throws IOException{
if(serverChannel != null){
serverChannel.close();
serverChannel.keyFor(selector).cancel();
}
clients.clear();
pendingChanges.clear();
pendingWriteData.clear();
selector.close();
}
}
}

View file

@ -35,56 +35,56 @@ import java.util.Iterator;
public class NioServer extends NioNetwork{
/**
* Creates a NioServer object which listens on localhost
*
* @param port the port to listen to
*/
public NioServer(int port) throws IOException {
this(null, port);
}
/**
* Creates a NioServer object which listens to a specific address
*
* @param address the address to listen to
* @param port the port to listen to
*/
public NioServer(InetAddress address, int port) throws IOException {
super(new InetSocketAddress(address, port));
}
protected Selector initSelector() throws IOException {
// Create a new selector
Selector socketSelector = SelectorProvider.provider().openSelector();
/**
* Creates a NioServer object which listens on localhost
*
* @param port the port to listen to
*/
public NioServer(int port) throws IOException {
this(null, port);
}
// Create a new non-blocking server socket channel
serverChannel = ServerSocketChannel.open();
serverChannel.socket().setReuseAddress(true);
serverChannel.configureBlocking(false);
/**
* Creates a NioServer object which listens to a specific address
*
* @param address the address to listen to
* @param port the port to listen to
*/
public NioServer(InetAddress address, int port) throws IOException {
super(new InetSocketAddress(address, port));
}
// Bind the server socket to the specified address and port
serverChannel.socket().bind(localAddress);
protected Selector initSelector() throws IOException {
// Create a new selector
Selector socketSelector = SelectorProvider.provider().openSelector();
// Register the server socket channel, indicating an interest in
// accepting new connections
serverChannel.register(socketSelector, SelectionKey.OP_ACCEPT);
// Create a new non-blocking server socket channel
serverChannel = ServerSocketChannel.open();
serverChannel.socket().setReuseAddress(true);
serverChannel.configureBlocking(false);
return socketSelector;
}
// Bind the server socket to the specified address and port
serverChannel.socket().bind(localAddress);
// Register the server socket channel, indicating an interest in
// accepting new connections
serverChannel.register(socketSelector, SelectionKey.OP_ACCEPT);
return socketSelector;
}
/**
* Broadcasts the message to all the connected clients
*
* @param data the data to broadcast
*/
public void broadcast(byte[] data){
synchronized(clients){
for(InetSocketAddress target : clients.keySet()){
send(target, data);
}
}
}
/**
* Broadcasts the message to all the connected clients
*
* @param data the data to broadcast
*/
public void broadcast(byte[] data){
synchronized(clients){
for(InetSocketAddress target : clients.keySet()){
send(target, data);
}
}
}
}

View file

@ -30,22 +30,22 @@ package zutil.net.nio.message;
* @author Ziver
*/
public abstract class EchoMessage implements Message{
private static final long serialVersionUID = 1L;
private boolean echo = false;
private static final long serialVersionUID = 1L;
private boolean echo = false;
/**
* @return true if this message is an echo/copy of an original message
*/
public boolean echo() {
return echo;
}
/**
* Called by the receiver to mark this message as an echo copy
*/
public void received() {
echo = true;
}
/**
* @return true if this message is an echo/copy of an original message
*/
public boolean echo() {
return echo;
}
/**
* Called by the receiver to mark this message as an echo copy
*/
public void received() {
echo = true;
}
}

View file

@ -27,9 +27,9 @@ package zutil.net.nio.response;
public class PrintResponseHandler extends ResponseHandler {
@Override
protected void responseEvent(Object rsp) {
System.out.println(rsp);
}
@Override
protected void responseEvent(Object rsp) {
System.out.println(rsp);
}
}

View file

@ -33,9 +33,9 @@ package zutil.net.nio.response;
*/
public interface RequestResponseMessage {
/**
* @return a unique id for this message
*/
long getResponseId();
/**
* @return a unique id for this message
*/
long getResponseId();
}

View file

@ -26,33 +26,33 @@ package zutil.net.nio.response;
// TODO: this class has a strange structure, should be refactored
public abstract class ResponseHandler {
private Object rsp = null;
private Object rsp = null;
public synchronized void handleResponse(Object rsp) {
this.rsp = rsp;
public synchronized void handleResponse(Object rsp) {
this.rsp = rsp;
responseEvent(rsp);
notify();
}
notify();
}
/**
* Blocks the calling thread until there is a response
*/
public void waitForResponse() {
while(!gotResponse()) {
try {
synchronized (this) {
/**
* Blocks the calling thread until there is a response
*/
public void waitForResponse() {
while(!gotResponse()) {
try {
synchronized (this) {
this.wait();
}
} catch (InterruptedException e) {}
}
}
} catch (InterruptedException e) {}
}
}
/**
* @return true if a response has been received
*/
public boolean gotResponse(){
return (rsp != null);
}
/**
* @return true if a response has been received
*/
public boolean gotResponse(){
return (rsp != null);
}
protected abstract void responseEvent(Object rsp);
protected abstract void responseEvent(Object rsp);
}

View file

@ -28,27 +28,27 @@ package zutil.net.nio.response;
import zutil.net.nio.message.EchoMessage;
public class StringResponseMessage extends EchoMessage implements RequestResponseMessage {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
private long responseId;
private String msg;
private long responseId;
private String msg;
public StringResponseMessage(String msg){
this.msg = msg;
responseId = (long)(Math.random()*Long.MAX_VALUE);
}
public StringResponseMessage(String msg){
this.msg = msg;
responseId = (long)(Math.random()*Long.MAX_VALUE);
}
public long getResponseId() {
return responseId;
}
public void setString(String msg){
this.msg = msg;
}
public String toString(){
return msg;
}
public void setString(String msg){
this.msg = msg;
}
public String toString(){
return msg;
}
}

View file

@ -28,17 +28,17 @@ import java.nio.channels.SocketChannel;
public class ChangeRequest {
public static final int REGISTER = 1;
public static final int CHANGEOPS = 2;
public SocketChannel socket;
public int type;
public int ops;
public static final int REGISTER = 1;
public static final int CHANGEOPS = 2;
public SocketChannel socket;
public int type;
public int ops;
public ChangeRequest(SocketChannel socket, int type, int ops) {
this.socket = socket;
this.type = type;
this.ops = ops;
}
public ChangeRequest(SocketChannel socket, int type, int ops) {
this.socket = socket;
this.type = type;
this.ops = ops;
}
}

View file

@ -28,28 +28,28 @@ import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
public class ClientData {
private SocketChannel socketChannel;
private long lastMessageReceived;
private SocketChannel socketChannel;
private long lastMessageReceived;
public ClientData(SocketChannel socketChannel){
this.socketChannel = socketChannel;
}
public ClientData(SocketChannel socketChannel){
this.socketChannel = socketChannel;
}
public SocketChannel getSocketChannel(){
return socketChannel;
}
public InetSocketAddress getAddress(){
return (InetSocketAddress) socketChannel.socket().getRemoteSocketAddress();
}
public void setLastMessageReceived(long time){
lastMessageReceived = time;
}
public long getLastMessageReceived(){
return lastMessageReceived;
}
public SocketChannel getSocketChannel(){
return socketChannel;
}
public InetSocketAddress getAddress(){
return (InetSocketAddress) socketChannel.socket().getRemoteSocketAddress();
}
public void setLastMessageReceived(long time){
lastMessageReceived = time;
}
public long getLastMessageReceived(){
return lastMessageReceived;
}
}

View file

@ -40,29 +40,29 @@ import java.util.logging.Logger;
public class StandardWorker extends ThreadedEventWorker {
private static Logger logger = LogUtil.getLogger();
private static Logger logger = LogUtil.getLogger();
private NioNetwork nio;
// Maps a responseId to a RspHandler
private Map<Long, ResponseHandler> rspEvents = new HashMap<>();
// Different services listening on specific messages
private Map<Class<?>, ThreadedEventWorker> services = new HashMap<>();
private NioNetwork nio;
// Maps a responseId to a RspHandler
private Map<Long, ResponseHandler> rspEvents = new HashMap<>();
// Different services listening on specific messages
private Map<Class<?>, ThreadedEventWorker> services = new HashMap<>();
/**
* Creates a new StandardWorker
*/
public StandardWorker(NioNetwork nio){
this.nio = nio;
}
/**
* Creates a new StandardWorker
*/
public StandardWorker(NioNetwork nio){
this.nio = nio;
}
@Override
public void messageEvent(WorkerEventData event) {
try {
logger.finer("Message: "+event.data.getClass().getName());
@Override
public void messageEvent(WorkerEventData event) {
try {
logger.finer("Message: "+event.data.getClass().getName());
if(event.data instanceof EchoMessage && !((EchoMessage)event.data).echo()){
// Echo back the received message
@ -86,29 +86,29 @@ public class StandardWorker extends ThreadedEventWorker {
services.get(event.data.getClass()).messageEvent(event);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Maps a Worker to a specific message
*
* @param messageClass the received message class
* @param worker the worker that should handle the specified message type
*/
public void registerWorker(Class<?> messageClass, ThreadedEventWorker worker){
services.put(messageClass, worker);
}
/**
* Un-maps a message class to a worker
*
/**
* Maps a Worker to a specific message
*
* @param messageClass the received message class
*/
public void unregisterWorker(Class<?> messageClass){
services.remove(messageClass);
}
* @param worker the worker that should handle the specified message type
*/
public void registerWorker(Class<?> messageClass, ThreadedEventWorker worker){
services.put(messageClass, worker);
}
/**
* Un-maps a message class to a worker
*
* @param messageClass the received message class
*/
public void unregisterWorker(Class<?> messageClass){
services.remove(messageClass);
}
/**
* Send a message with a defined response handler
@ -117,10 +117,10 @@ public class StandardWorker extends ThreadedEventWorker {
* @param message the message object
* @param handler the handler that should be called when a response is received
*/
public void send(SocketAddress address, RequestResponseMessage message, ResponseHandler handler) throws IOException {
// Register the response handler
rspEvents.put(message.getResponseId(), handler);
public void send(SocketAddress address, RequestResponseMessage message, ResponseHandler handler) throws IOException {
// Register the response handler
rspEvents.put(message.getResponseId(), handler);
nio.send(address, Converter.toBytes(message));
}
nio.send(address, Converter.toBytes(message));
}
}

View file

@ -25,24 +25,24 @@
package zutil.net.nio.worker;
public abstract class ThreadedEventWorker extends Worker implements Runnable{
private Thread thread;
private Thread thread;
public ThreadedEventWorker(){
thread = new Thread(this);
thread.start();
}
public ThreadedEventWorker(){
thread = new Thread(this);
thread.start();
}
public void run() {
while(true) {
try{
// Wait for data to become available
messageEvent(pollEvent());
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void run() {
while(true) {
try{
// Wait for data to become available
messageEvent(pollEvent());
} catch (Exception e) {
e.printStackTrace();
}
}
}
public abstract void messageEvent(WorkerEventData e);
public abstract void messageEvent(WorkerEventData e);
}

View file

@ -32,37 +32,37 @@ import java.util.List;
public abstract class Worker {
private LinkedList<WorkerEventData> queue = new LinkedList<>();
private LinkedList<WorkerEventData> queue = new LinkedList<>();
public void processData(NioNetwork server, SocketAddress remote, Object data) {
synchronized(queue) {
queue.add(new WorkerEventData(server, remote, data));
queue.notify();
}
}
public void processData(NioNetwork server, SocketAddress remote, Object data) {
synchronized(queue) {
queue.add(new WorkerEventData(server, remote, data));
queue.notify();
}
}
/**
* @return true if there is a event in the queue
*/
protected boolean hasEvent(){
return !queue.isEmpty();
}
/**
* Polls a event from the list or blocks until there is a event available
/**
* @return true if there is a event in the queue
*/
protected boolean hasEvent(){
return !queue.isEmpty();
}
/**
* Polls a event from the list or blocks until there is a event available
*
* @return the next event
*/
protected WorkerEventData pollEvent(){
synchronized(queue) {
while (queue.isEmpty()) {
try {
queue.wait();
} catch (InterruptedException e) {}
}
}
return queue.poll();
}
* @return the next event
*/
protected WorkerEventData pollEvent(){
synchronized(queue) {
while (queue.isEmpty()) {
try {
queue.wait();
} catch (InterruptedException e) {}
}
}
return queue.poll();
}
}

View file

@ -31,14 +31,14 @@ import java.nio.channels.SocketChannel;
public class WorkerEventData {
public NioNetwork network;
public SocketAddress remoteAddress;
public Object data;
public NioNetwork network;
public SocketAddress remoteAddress;
public Object data;
public WorkerEventData(NioNetwork server, SocketAddress remoteAddress, Object data) {
this.network = server;
this.remoteAddress = remoteAddress;
this.data = data;
}
public WorkerEventData(NioNetwork server, SocketAddress remoteAddress, Object data) {
this.network = server;
this.remoteAddress = remoteAddress;
this.data = data;
}
}

View file

@ -30,5 +30,5 @@ package zutil.net.nio.worker.chat;
*
*/
public interface ChatListener {
public void messageAction(String msg, String room);
public void messageAction(String msg, String room);
}

Some files were not shown because too many files have changed in this diff Show more