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

@ -45,15 +45,5 @@
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" /> <orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Maven: com.carrotsearch:junit-benchmarks:0.7.2" level="project" /> <orderEntry type="library" name="Maven: com.carrotsearch:junit-benchmarks:0.7.2" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.2.1" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
<orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />
<orderEntry type="library" name="Maven: xml-apis:xml-apis:1.0.b2" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" />
<orderEntry type="library" name="Maven: mysql:mysql-connector-java:5.1.36" level="project" />
<orderEntry type="library" name="Maven: org.xerial:sqlite-jdbc:3.8.11.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Maven: com.carrotsearch:junit-benchmarks:0.7.2" level="project" />
</component> </component>
</module> </module>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -38,104 +38,104 @@ import java.util.LinkedList;
*/ */
public class EuclideansAlgo { public class EuclideansAlgo {
/** /**
* Simple Test * Simple Test
* @param args * @param args
*/ */
public static void main(String[] args){ public static void main(String[] args){
MultiPrintStream.out.println("*** Correct Answer: "); 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("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("GCD: 1");
MultiPrintStream.out.println("*** Integer:"); MultiPrintStream.out.println("*** Integer:");
MultiPrintStream.out.dump(calcGenerators(60728973, 160523347)); MultiPrintStream.out.dump(calcGenerators(60728973, 160523347));
MultiPrintStream.out.println("GCD: "+calc(60728973, 160523347)); MultiPrintStream.out.println("GCD: "+calc(60728973, 160523347));
MultiPrintStream.out.println("*** BigInteger: "); MultiPrintStream.out.println("*** BigInteger: ");
MultiPrintStream.out.dump(calcGenerators(new BigInteger("60728973"), new BigInteger("160523347"))); MultiPrintStream.out.dump(calcGenerators(new BigInteger("60728973"), new BigInteger("160523347")));
MultiPrintStream.out.println("GCD: "+calc(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 * Runs the Euclidean algorithm on the two input
* values. * values.
* *
* @param a is the first integer * @param a is the first integer
* @param b is the second integer * @param b is the second integer
* @return a integer containing the GCD of the integers * @return a integer containing the GCD of the integers
*/ */
public static int calc(int a, int b){ public static int calc(int a, int b){
int t; int t;
while( b != 0 ){ while( b != 0 ){
t = b; t = b;
b = a % b; b = a % b;
a = t; a = t;
} }
return a; return a;
} }
/** /**
* Runs the Euclidean algorithm on the two input * Runs the Euclidean algorithm on the two input
* values. * values.
* *
* @param a is the first BigInteger * @param a is the first BigInteger
* @param b is the second BigInteger * @param b is the second BigInteger
* @return a BigInteger containing the GCD of the BigIntegers * @return a BigInteger containing the GCD of the BigIntegers
*/ */
public static BigInteger calc(BigInteger a, BigInteger b){ public static BigInteger calc(BigInteger a, BigInteger b){
BigInteger t; BigInteger t;
while( !b.equals(BigInteger.ZERO) ){ while( !b.equals(BigInteger.ZERO) ){
t = b; t = b;
b = a.mod( b ); b = a.mod( b );
a = t; a = t;
} }
return a; return a;
} }
/** /**
* Runs the Euclidean algorithm on the two input * Runs the Euclidean algorithm on the two input
* values to find the generators for the values. * values to find the generators for the values.
* *
* @param a is the first integer * @param a is the first integer
* @param b is the second integer * @param b is the second integer
* @return a list of integers that is generators for a and b * @return a list of integers that is generators for a and b
*/ */
public static LinkedList<Integer> calcGenerators(int a, int b){ public static LinkedList<Integer> calcGenerators(int a, int b){
LinkedList<Integer> list = new LinkedList<Integer>(); LinkedList<Integer> list = new LinkedList<Integer>();
int t; int t;
while( b != 0 ){ while( b != 0 ){
list.add( a/b ); list.add( a/b );
t = b; t = b;
b = a % b; b = a % b;
a = t; a = t;
} }
return list; return list;
} }
/** /**
* Runs the Euclidean algorithm on the two input * Runs the Euclidean algorithm on the two input
* values to find the generators for the values. * values to find the generators for the values.
* *
* @param a is the first BigInteger * @param a is the first BigInteger
* @param b is the second BigInteger * @param b is the second BigInteger
* @return a list of BigIntegers that is generators of a and b * @return a list of BigIntegers that is generators of a and b
*/ */
public static LinkedList<BigInteger> calcGenerators(BigInteger a, BigInteger b){ public static LinkedList<BigInteger> calcGenerators(BigInteger a, BigInteger b){
LinkedList<BigInteger> list = new LinkedList<BigInteger>(); LinkedList<BigInteger> list = new LinkedList<BigInteger>();
BigInteger t; BigInteger t;
while( !b.equals(BigInteger.ZERO) ){ while( !b.equals(BigInteger.ZERO) ){
list.add( new BigInteger("0").add( a.divide( b ) ) ); list.add( new BigInteger("0").add( a.divide( b ) ) );
t = b; t = b;
b = a.mod( b ); b = a.mod( b );
a = t; a = t;
} }
return list; 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> * @see <a href="http://en.wikipedia.org/wiki/Shanks-Tonelli_algorithm">Wikipedia</a>
*/ */
public class ShanksTonelliAlgo { public class ShanksTonelliAlgo {
public static BigInteger calc(BigInteger n, BigInteger p){ public static BigInteger calc(BigInteger n, BigInteger p){
BigInteger nOrg = n; BigInteger nOrg = n;
BigInteger S = null, V, R, U, X; BigInteger S = null, V, R, U, X;
BigInteger ONE = BigInteger.ONE; BigInteger ONE = BigInteger.ONE;
BigInteger TWO = BigInteger.valueOf( 2 ); BigInteger TWO = BigInteger.valueOf( 2 );
BigInteger Q = p.add( ONE ).divide( TWO ); BigInteger Q = p.add( ONE ).divide( TWO );
switch( p.mod( BigInteger.valueOf(4) ).intValue() ){ switch( p.mod( BigInteger.valueOf(4) ).intValue() ){
case 3: case 3:
S = n.pow( Q.divide( TWO ).intValue() ).mod( p ); S = n.pow( Q.divide( TWO ).intValue() ).mod( p );
break; break;
case 1: case 1:
S = ONE; S = ONE;
n = n.subtract( ONE ); n = n.subtract( ONE );
while (n.divide( p ).compareTo( ONE ) == 0) { while (n.divide( p ).compareTo( ONE ) == 0) {
S = S.add( ONE ); S = S.add( ONE );
//n = (n-2s+1) mod p //n = (n-2s+1) mod p
n = n.subtract( TWO.multiply( S ) ).add( ONE ).mod( p ); n = n.subtract( TWO.multiply( S ) ).add( ONE ).mod( p );
if (n.compareTo( BigInteger.ZERO ) == 0){ if (n.compareTo( BigInteger.ZERO ) == 0){
return S; return S;
} }
} }
Q = Q.divide( TWO ); Q = Q.divide( TWO );
V = ONE; V = ONE;
R = S; R = S;
U = ONE; U = ONE;
while (Q.compareTo( BigInteger.ZERO ) > 0) { while (Q.compareTo( BigInteger.ZERO ) > 0) {
X = R.pow(2).subtract( n.multiply( U.pow(2) ) ).mod( p ); X = R.pow(2).subtract( n.multiply( U.pow(2) ) ).mod( p );
U = TWO.multiply( R ).multiply( U ).mod( p ); U = TWO.multiply( R ).multiply( U ).mod( p );
R = X; R = X;
if ( Q.testBit(0) ){ if ( Q.testBit(0) ){
X = S.multiply( R ).subtract( n.multiply(V).multiply(U) ).mod( p ); X = S.multiply( R ).subtract( n.multiply(V).multiply(U) ).mod( p );
V = V.multiply(R).add( S.multiply(U) ).mod( p ); V = V.multiply(R).add( S.multiply(U) ).mod( p );
S = X; S = X;
} }
Q = Q.divide( TWO ); Q = Q.divide( TWO );
} }
} }
if( S != null && S.multiply( S ).mod( p ).compareTo( nOrg ) != 0 ){ if( S != null && S.multiply( S ).mod( p ).compareTo( nOrg ) != 0 ){
return null; return null;
} }
return S; return S;
/* /*
//p-1 = Q*2^S //p-1 = Q*2^S
BigInteger S = null, Q = null, R = null, V = null, W = null; BigInteger S = null, Q = null, R = null, V = null, W = null;
//Q = ( 2^S )/( 1-p ); //Q = ( 2^S )/( 1-p );
p-1 = ( 2^S )/( 1-p ) * 2^S; p-1 = ( 2^S )/( 1-p ) * 2^S;
// R = n^( (Q+1)/2 ) mod p // R = n^( (Q+1)/2 ) mod p
R = n.pow( Q.add(BigInteger.ONE).divide(BigInteger.valueOf(2)).intValue() ).mod( p ); R = n.pow( Q.add(BigInteger.ONE).divide(BigInteger.valueOf(2)).intValue() ).mod( p );
// V = W^Q mod p // V = W^Q mod p
V = W.pow( Q.intValue() ).mod( p ); V = W.pow( Q.intValue() ).mod( p );
for(int i=S.intValue(); true ;){ for(int i=S.intValue(); true ;){
while( true ){ while( true ){
i--; i--;
// 1 = ( ( R^2 * n^-1 )^2^i ) mod p // 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 ) if( ( R.pow(2).multiply( n.pow(-1) ) ).pow( (int)Math.pow(2, i) ).mod( p ).compareTo( BigInteger.ONE ) == 0 )
break; break;
} }
if(i == 0) return R; if(i == 0) return R;
//R = ( RV^(2^(S-i-1)) ) mod p //R = ( RV^(2^(S-i-1)) ) mod p
else R = ( R.multiply( V.pow( (int)Math.pow( 2, S.intValue()-i-1) ) )).mod( p ); else R = ( R.multiply( V.pow( (int)Math.pow( 2, S.intValue()-i-1) ) )).mod( p );
} }
*/ */
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -28,42 +28,39 @@ import java.util.ArrayList;
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
public class SortableArrayList<T> implements SortableDataList<T>{ public class SortableArrayList<T> implements SortableDataList<T>{
private ArrayList<T> list; private ArrayList<T> list;
public SortableArrayList(ArrayList<T> list){ public SortableArrayList(ArrayList<T> list){
this.list = list; this.list = list;
} }
public T get(int i) { public T get(int i) {
return list.get(i); return list.get(i);
} }
public void set(int i, T o){ public void set(int i, T o){
list.set(i, o); list.set(i, o);
} }
public int size() { public int size() {
return list.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

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

View file

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

View file

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

View file

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

View file

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

View file

@ -37,162 +37,162 @@ import java.util.TimerTask;
* @author Ziver * @author Ziver
*/ */
public class DBConnectionPool extends TimerTask implements Closeable{ public class DBConnectionPool extends TimerTask implements Closeable{
public static final long DEFAULT_TIMEOUT = 10*60*60*1000; // 10 minutes; public static final long DEFAULT_TIMEOUT = 10*60*60*1000; // 10 minutes;
public static final int DEFAULT_MAX_SIZE = 5; public static final int DEFAULT_MAX_SIZE = 5;
// DB details // DB details
private DBMS dbms; private DBMS dbms;
private String url; private String url;
private String db; private String db;
private String user; private String user;
private String password; private String password;
// Pool details // Pool details
private int max_conn; private int max_conn;
private long timeout; private long timeout;
private Timer timeout_timer; private Timer timeout_timer;
protected class PoolItem{ protected class PoolItem{
public DBConnection conn; public DBConnection conn;
public long timestamp; public long timestamp;
public boolean equals(Object o){ public boolean equals(Object o){
return conn.equals(o); return conn.equals(o);
} }
} }
// The pool // The pool
private LinkedList<PoolItem> inusePool; private LinkedList<PoolItem> inusePool;
private LinkedList<PoolItem> readyPool; private LinkedList<PoolItem> readyPool;
/** /**
* Creates a new pool of DB connections * Creates a new pool of DB connections
* *
* @param dbms is the DB type * @param dbms is the DB type
* @param url is the URL to the DB * @param url is the URL to the DB
* @param db is the name of the database * @param db is the name of the database
* @param user is the user name to the DB * @param user is the user name to the DB
* @param password is the password 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{ public DBConnectionPool(DBMS dbms, String url, String db, String user, String password) throws Exception{
this.dbms = dbms; this.dbms = dbms;
this.url = url; this.url = url;
this.db = db; this.db = db;
this.user = user; this.user = user;
this.password = password; this.password = password;
inusePool = new LinkedList<PoolItem>(); inusePool = new LinkedList<PoolItem>();
readyPool = new LinkedList<PoolItem>(); readyPool = new LinkedList<PoolItem>();
this.setTimeout(DEFAULT_TIMEOUT); this.setTimeout(DEFAULT_TIMEOUT);
this.setMaxSize(DEFAULT_MAX_SIZE); this.setMaxSize(DEFAULT_MAX_SIZE);
} }
/** /**
* Registers a Connection to the pool * Registers a Connection to the pool
* *
* @param conn is the Connection to register * @param conn is the Connection to register
*/ */
protected void addConnection(DBConnection conn){ protected void addConnection(DBConnection conn){
PoolItem item = new PoolItem(); PoolItem item = new PoolItem();
item.conn = conn; item.conn = conn;
readyPool.addLast(item); readyPool.addLast(item);
} }
/** /**
* Removes an connection from the pool * Removes an connection from the pool
* *
* @param conn is the connection to remove * @param conn is the connection to remove
*/ */
protected void removeConnection(DBConnection conn){ protected void removeConnection(DBConnection conn){
inusePool.remove(conn); inusePool.remove(conn);
readyPool.remove(conn); readyPool.remove(conn);
} }
/** /**
* Lease one connection from the pool * Lease one connection from the pool
* *
* @return an DB connection or null if the pool is empty * @return an DB connection or null if the pool is empty
*/ */
public synchronized DBConnection getConnection() throws Exception{ public synchronized DBConnection getConnection() throws Exception{
if(readyPool.isEmpty()){ if(readyPool.isEmpty()){
if( size() < max_conn ){ if( size() < max_conn ){
DBConnection conn = new DBConnection(dbms, url, db, user, password); DBConnection conn = new DBConnection(dbms, url, db, user, password);
conn.setPool( this ); conn.setPool( this );
addConnection( conn ); addConnection( conn );
return conn; return conn;
} }
return null; return null;
} }
else{ else{
PoolItem item = readyPool.poll(); PoolItem item = readyPool.poll();
inusePool.addLast(item); inusePool.addLast(item);
item.timestamp = System.currentTimeMillis(); item.timestamp = System.currentTimeMillis();
return item.conn; return item.conn;
} }
} }
/** /**
* Registers the Connection as not used * Registers the Connection as not used
* *
* @param conn is the connection that is not used anymore * @param conn is the connection that is not used anymore
*/ */
protected synchronized void releaseConnection(DBConnection conn){ protected synchronized void releaseConnection(DBConnection conn){
int index = inusePool.indexOf(conn); int index = inusePool.indexOf(conn);
PoolItem item = inusePool.remove(index); PoolItem item = inusePool.remove(index);
readyPool.addLast(item); readyPool.addLast(item);
} }
/** /**
* @return the current size of the pool * @return the current size of the pool
*/ */
public int size(){ public int size(){
return inusePool.size() + readyPool.size(); return inusePool.size() + readyPool.size();
} }
/** /**
* Closes all the connections * Closes all the connections
*/ */
public synchronized void close(){ public synchronized void close(){
for( PoolItem item : inusePool ){ for( PoolItem item : inusePool ){
item.conn.forceClose(); item.conn.forceClose();
} }
inusePool.clear(); inusePool.clear();
for( PoolItem item : readyPool ){ for( PoolItem item : readyPool ){
item.conn.forceClose(); item.conn.forceClose();
} }
readyPool.clear(); readyPool.clear();
} }
/** /**
* Set the max size of the pool * Set the max size of the pool
*/ */
public void setMaxSize(int max){ public void setMaxSize(int max){
this.max_conn = max; this.max_conn = max;
} }
/** /**
* Sets the timeout of the Connections * Sets the timeout of the Connections
*/ */
public synchronized void setTimeout(long timeout){ public synchronized void setTimeout(long timeout){
this.timeout = timeout; this.timeout = timeout;
if(timeout_timer!=null) if(timeout_timer!=null)
timeout_timer.cancel(); timeout_timer.cancel();
timeout_timer = new Timer(); timeout_timer = new Timer();
timeout_timer.schedule(this, 0, timeout / 2); timeout_timer.schedule(this, 0, timeout / 2);
} }
/** /**
* Checks every DB connection if they are valid and has not timed out * Checks every DB connection if they are valid and has not timed out
*/ */
public void run(){ public void run(){
long stale = System.currentTimeMillis() - timeout; long stale = System.currentTimeMillis() - timeout;
for(PoolItem item : inusePool){ for(PoolItem item : inusePool){
if( !item.conn.valid() && stale > item.timestamp ) { if( !item.conn.valid() && stale > item.timestamp ) {
removeConnection(item.conn); removeConnection(item.conn);
item.conn.forceClose(); item.conn.forceClose();
} }
} }
} }
} }

View file

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

View file

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

View file

@ -29,11 +29,11 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
public interface SQLResultHandler<T> { public interface SQLResultHandler<T> {
/** /**
* Is called to handle an result from an query. * Is called to handle an result from an query.
* *
* @param stmt is the query * @param stmt is the query
* @param result is the ResultSet * @param result is the ResultSet
*/ */
public T handleQueryResult(Statement stmt, ResultSet result) throws SQLException; 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<>(); 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; private String tableName;
/** The name of the id column **/ /** The name of the id column **/
private String idColumnName; private String idColumnName;

View file

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

View file

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

View file

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

View file

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

View file

@ -37,163 +37,163 @@ import java.awt.image.BufferedImage;
* @author Ziver * @author Ziver
*/ */
public abstract class ImageFilterProcessor { public abstract class ImageFilterProcessor {
private BufferedImage img; private BufferedImage img;
private ProgressListener<ImageFilterProcessor,?> progress; private ProgressListener<ImageFilterProcessor,?> progress;
public ImageFilterProcessor(BufferedImage img){ public ImageFilterProcessor(BufferedImage img){
this.img = img; this.img = img;
} }
/** /**
* Sets the listener * Sets the listener
* @param listener is the listener, null to disable the progress * @param listener is the listener, null to disable the progress
*/ */
public void setProgressListener(ProgressListener<ImageFilterProcessor,?> listener){ public void setProgressListener(ProgressListener<ImageFilterProcessor,?> listener){
this.progress = listener; this.progress = listener;
} }
/** /**
* Returns the listener * Returns the listener
*/ */
public ProgressListener<?,?> getProgressListener(){ public ProgressListener<?,?> getProgressListener(){
return this.progress; return this.progress;
} }
/** /**
* Sets the progress in percent * Sets the progress in percent
*/ */
protected void setProgress(double percent){ protected void setProgress(double percent){
if(progress != null) progress.progressUpdate(this, null, percent); if(progress != null) progress.progressUpdate(this, null, percent);
} }
/** /**
* Applies a effect to a given image * Applies a effect to a given image
* *
* @param effect The effect to use * @param effect The effect to use
* @param img The image to process * @param img The image to process
* @return The processed image * @return The processed image
*/ */
public static ImageFilterProcessor getProcessor(String effect, BufferedImage img) throws InstantiationException, IllegalAccessException, ClassNotFoundException, InterruptedException{ public static ImageFilterProcessor getProcessor(String effect, BufferedImage img) throws InstantiationException, IllegalAccessException, ClassNotFoundException, InterruptedException{
ImageFilterProcessor processor = (ImageFilterProcessor)Class.forName(effect).newInstance(); ImageFilterProcessor processor = (ImageFilterProcessor)Class.forName(effect).newInstance();
processor.img = img; processor.img = img;
return processor; return processor;
} }
/** /**
* Adds the chosen effect to the image * Adds the chosen effect to the image
* *
* @return The Image with the effect * @return The Image with the effect
*/ */
public BufferedImage process() throws InterruptedException{ public BufferedImage process() throws InterruptedException{
int cols = img.getWidth(); int cols = img.getWidth();
int rows = img.getHeight(); int rows = img.getHeight();
if(cols < 0 || rows < 0){ if(cols < 0 || rows < 0){
throw new InterruptedException("Image not Loaded!!!"); throw new InterruptedException("Image not Loaded!!!");
} }
// converts the img to raw data // converts the img to raw data
int[][][] data = convertToArray(img, cols, rows); int[][][] data = convertToArray(img, cols, rows);
//processes the image //processes the image
data = process(data); data = process(data);
//converts back the image //converts back the image
return convertToImage(data, data[0].length, data.length); return convertToImage(data, data[0].length, data.length);
} }
/** /**
* Creates a Integer array with the pixel data of the image <XMP> * Creates a Integer array with the pixel data of the image <XMP>
* int[row][col][4] * int[row][col][4]
* 0 -> Alpha data * 0 -> Alpha data
* Red data * Red data
* Green data * Green data
* 4 -> Blue data </XMP> * 4 -> Blue data </XMP>
* *
* @param img is the image to convert * @param img is the image to convert
* @param cols is the columns of the image * @param cols is the columns of the image
* @param rows is the rows of the image * @param rows is the rows of the image
* @return A is the integer array * @return A is the integer array
*/ */
public static int[][][] convertToArray(BufferedImage img, int cols, int rows) throws InterruptedException{ public static int[][][] convertToArray(BufferedImage img, int cols, int rows) throws InterruptedException{
int[][][] data = new int[rows][cols][4]; int[][][] data = new int[rows][cols][4];
// Reads in the image to a one dim array // Reads in the image to a one dim array
int[] pixels = img.getRGB(0, 0, cols, rows, null, 0, cols); int[] pixels = img.getRGB(0, 0, cols, rows, null, 0, cols);
// Read the pixel data and put it in the data array // Read the pixel data and put it in the data array
for(int y=0; y<rows ;y++){ for(int y=0; y<rows ;y++){
// reading a row // reading a row
int[] aRow = new int[cols]; int[] aRow = new int[cols];
for(int x=0; x<cols ;x++){ for(int x=0; x<cols ;x++){
int element = y * cols + x; int element = y * cols + x;
aRow[x] = pixels[element]; aRow[x] = pixels[element];
} }
// Reading in the color data // Reading in the color data
for(int x=0; x<cols ;x++){ for(int x=0; x<cols ;x++){
//Alpha data //Alpha data
data[y][x][0] = ((aRow[x] >> 24) & 0xFF); data[y][x][0] = ((aRow[x] >> 24) & 0xFF);
//Red data //Red data
data[y][x][1] = ((aRow[x] >> 16) & 0xFF); data[y][x][1] = ((aRow[x] >> 16) & 0xFF);
//Green data //Green data
data[y][x][2] = ((aRow[x] >> 8) & 0xFF); data[y][x][2] = ((aRow[x] >> 8) & 0xFF);
//Blue data //Blue data
data[y][x][3] = ((aRow[x])& 0xFF); data[y][x][3] = ((aRow[x])& 0xFF);
} }
} }
return data; return data;
} }
/** /**
* Converts a pixel data array to a java Image object * Converts a pixel data array to a java Image object
* *
* @param pixels is the pixel data array * @param pixels is the pixel data array
* @param cols is the columns of the image * @param cols is the columns of the image
* @param rows is the rows of the image * @param rows is the rows of the image
* @return A Image * @return A Image
*/ */
public static BufferedImage convertToImage(int[][][] pixels, int cols, int rows){ public static BufferedImage convertToImage(int[][][] pixels, int cols, int rows){
int[] data = new int[cols * rows * 4]; int[] data = new int[cols * rows * 4];
//Move the data into the 1D array. Note the //Move the data into the 1D array. Note the
// use of the bitwise OR operator and the // use of the bitwise OR operator and the
// bitwise left-shift operators to put the // bitwise left-shift operators to put the
// four 8-bit bytes into each int. // four 8-bit bytes into each int.
int index = 0; int index = 0;
for(int y=0; y<rows ;y++){ for(int y=0; y<rows ;y++){
for(int x=0; x< cols ;x++){ for(int x=0; x< cols ;x++){
data[index] = ((pixels[y][x][0] << 24) & 0xFF000000) data[index] = ((pixels[y][x][0] << 24) & 0xFF000000)
| ((pixels[y][x][1] << 16) & 0x00FF0000) | ((pixels[y][x][1] << 16) & 0x00FF0000)
| ((pixels[y][x][2] << 8) & 0x0000FF00) | ((pixels[y][x][2] << 8) & 0x0000FF00)
| ((pixels[y][x][3]) & 0x000000FF); | ((pixels[y][x][3]) & 0x000000FF);
index++; index++;
} }
} }
BufferedImage img = new BufferedImage(cols, rows, BufferedImage.TYPE_4BYTE_ABGR); BufferedImage img = new BufferedImage(cols, rows, BufferedImage.TYPE_4BYTE_ABGR);
img.setRGB(0, 0, cols, rows, data, 0, cols); img.setRGB(0, 0, cols, rows, data, 0, cols);
return img; return img;
} }
/** /**
* Runs the image thru the processor * Runs the image thru the processor
* *
* @param data is the raw image to apply the effect to. This will NOT be altered * @param data is the raw image to apply the effect to. This will NOT be altered
*/ */
public int[][][] process(int[][][] data){ public int[][][] process(int[][][] data){
return process(data, 0, 0, data[0].length, data.length); return process(data, 0, 0, data[0].length, data.length);
} }
/** /**
* The underlying effect is run here * The underlying effect is run here
* *
* @param data is the raw image to apply the effect to. This will NOT be altered * @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 startX is the x pixel of the image to start from
* @param startY is the y 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 stopX is the x pixel of the image to stop
* @param stopY is the y 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 * @return either the modified data parameter or an new array
*/ */
public abstract int[][][] process(int[][][] data, int startX, int startY, int stopX, int stopY); 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 { public class ImageUtil {
/** /**
* Resizes a BufferedImage * Resizes a BufferedImage
* *
* @param source is the image to resize * @param source is the image to resize
* @param width is the wanted width * @param width is the wanted width
* @param height is the wanted height * @param height is the wanted height
* @param keep_aspect is if the aspect ratio of the image should be kept * @param keep_aspect is if the aspect ratio of the image should be kept
* @return the resized image * @return the resized image
*/ */
public static BufferedImage scale(BufferedImage source, int width, int height, boolean keep_aspect){ public static BufferedImage scale(BufferedImage source, int width, int height, boolean keep_aspect){
double scale_width = (double)width / source.getWidth(); double scale_width = (double)width / source.getWidth();
double scale_height = (double)height / source.getHeight(); double scale_height = (double)height / source.getHeight();
// aspect calculation // aspect calculation
if(keep_aspect){ if(keep_aspect){
if(scale_width * source.getHeight() > height){ if(scale_width * source.getHeight() > height){
scale_width = scale_height; scale_width = scale_height;
}else{ }else{
scale_height = scale_width; scale_height = scale_width;
} }
} }
BufferedImage tmp = new BufferedImage( BufferedImage tmp = new BufferedImage(
(int)(scale_width * source.getWidth()), (int)(scale_width * source.getWidth()),
(int)(scale_height * source.getHeight()), (int)(scale_height * source.getHeight()),
BufferedImage.TYPE_INT_RGB); BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = tmp.createGraphics(); Graphics2D g2d = tmp.createGraphics();
AffineTransform at = AffineTransform.getScaleInstance(scale_width, scale_height); AffineTransform at = AffineTransform.getScaleInstance(scale_width, scale_height);
g2d.drawRenderedImage(source, at); g2d.drawRenderedImage(source, at);
g2d.dispose(); g2d.dispose();
return tmp; return tmp;
} }
/** /**
* Crops a image to a specific aspect ration * Crops a image to a specific aspect ration
* *
* @param image is the actual image to crop * @param image is the actual image to crop
* @param aspect is the aspect ratio to convert the image to * @param aspect is the aspect ratio to convert the image to
* @return a new image with the specified aspect ratio * @return a new image with the specified aspect ratio
*/ */
public static BufferedImage cropToAspectRatio(BufferedImage image, float aspect){ public static BufferedImage cropToAspectRatio(BufferedImage image, float aspect){
int x = 0, y = 0; int x = 0, y = 0;
int width = image.getWidth(); int width = image.getWidth();
int height = image.getHeight(); int height = image.getHeight();
// Check if the width is larger than the heigth // Check if the width is larger than the heigth
if( width > height ){ if( width > height ){
width = (int) (height * aspect); width = (int) (height * aspect);
x = image.getWidth()/2 - width/2; x = image.getWidth()/2 - width/2;
} }
else{ else{
height = (int) (width * aspect); height = (int) (width * aspect);
y = image.getHeight()/2 - height/2; 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 * This function crops the image to the aspect ratio of
* the width and height and then scales the image to the * the width and height and then scales the image to the
* given values * given values
* *
* @param source is the image to resize * @param source is the image to resize
* @param width is the wanted width * @param width is the wanted width
* @param height is the wanted height * @param height is the wanted height
* @return a new image with the specified width and height * @return a new image with the specified width and height
*/ */
public static BufferedImage cropScale(BufferedImage source, int width, int height){ public static BufferedImage cropScale(BufferedImage source, int width, int height){
float aspect = width/height; float aspect = width/height;
BufferedImage tmp = cropToAspectRatio(source, aspect); BufferedImage tmp = cropToAspectRatio(source, aspect);
tmp = scale(tmp, width, height, false); tmp = scale(tmp, width, height, false);
return tmp; return tmp;
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -36,138 +36,138 @@ import java.util.logging.LogRecord;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class CompactLogFormatter extends Formatter{ public class CompactLogFormatter extends Formatter{
/** The split pattern where the **/ /** The split pattern where the **/
private static final Pattern splitter = Pattern.compile("\n"); private static final Pattern splitter = Pattern.compile("\n");
/** the stream should print time stamp **/ /** the stream should print time stamp **/
private boolean timeStamp = true; private boolean timeStamp = true;
/** The time stamp style **/ /** The time stamp style **/
private SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); private SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
/** If displaying class names are enabled **/ /** If displaying class names are enabled **/
private boolean className = true; private boolean className = true;
/** If displaying method names are enabled **/ /** If displaying method names are enabled **/
private boolean methodName = false; private boolean methodName = false;
/** Specifies the max length of the longest class name **/ /** Specifies the max length of the longest class name **/
private int max_class_name = 0; private int max_class_name = 0;
/** Cache for the class padding **/ /** Cache for the class padding **/
private static HashMap<String,String> padd_cache = new HashMap<String,String>(); private static HashMap<String,String> padd_cache = new HashMap<String,String>();
/** Date temp file **/ /** Date temp file **/
private Date date = new Date(); private Date date = new Date();
@Override @Override
public String format(LogRecord record) { public String format(LogRecord record) {
StringBuilder prefix = new StringBuilder(); StringBuilder prefix = new StringBuilder();
if( timeStamp ){ if( timeStamp ){
date.setTime( record.getMillis() ); date.setTime( record.getMillis() );
prefix.append(dateFormatter.format(date)); prefix.append(dateFormatter.format(date));
prefix.append(' '); prefix.append(' ');
} }
switch( record.getLevel().intValue() ){ switch( record.getLevel().intValue() ){
case /* SEVERE */ 1000: prefix.append("[SEVERE] "); break; case /* SEVERE */ 1000: prefix.append("[SEVERE] "); break;
case /* WARNING */ 900 : prefix.append("[WARNING]"); break; case /* WARNING */ 900 : prefix.append("[WARNING]"); break;
case /* INFO */ 800 : prefix.append("[INFO] "); break; case /* INFO */ 800 : prefix.append("[INFO] "); break;
case /* CONFIG */ 700 : prefix.append("[CONFIG] "); break; case /* CONFIG */ 700 : prefix.append("[CONFIG] "); break;
case /* FINE */ 500 : prefix.append("[FINE] "); break; case /* FINE */ 500 : prefix.append("[FINE] "); break;
case /* FINER */ 400 : prefix.append("[FINER] "); break; case /* FINER */ 400 : prefix.append("[FINER] "); break;
case /* FINEST */ 300 : prefix.append("[FINEST] "); break; case /* FINEST */ 300 : prefix.append("[FINEST] "); break;
} }
prefix.append(' '); prefix.append(' ');
if( className ){ if( className ){
prefix.append(paddClassName(record.getSourceClassName())); prefix.append(paddClassName(record.getSourceClassName()));
} }
if(methodName){ if(methodName){
prefix.append(record.getSourceMethodName()); prefix.append(record.getSourceMethodName());
} }
prefix.append(": "); prefix.append(": ");
StringBuilder ret = new StringBuilder(); StringBuilder ret = new StringBuilder();
if( record.getMessage() != null ){ if( record.getMessage() != null ){
String[] array = splitter.split( record.getMessage() ); String[] array = splitter.split( record.getMessage() );
for( int i=0; i<array.length ;++i ){ for( int i=0; i<array.length ;++i ){
if( i!=0 ) if( i!=0 )
ret.append( '\n' ); ret.append( '\n' );
if( prefix.length() > 0 ) if( prefix.length() > 0 )
ret.append( prefix ); ret.append( prefix );
ret.append( array[i] ); ret.append( array[i] );
} }
ret.append( '\n' ); ret.append( '\n' );
} }
if( record.getThrown() != null ){ if( record.getThrown() != null ){
StringOutputStream out = new StringOutputStream(); StringOutputStream out = new StringOutputStream();
record.getThrown().printStackTrace(new PrintStream(out)); record.getThrown().printStackTrace(new PrintStream(out));
String[] array = splitter.split( out.toString() ); String[] array = splitter.split( out.toString() );
for( int i=0; i<array.length ;++i ){ for( int i=0; i<array.length ;++i ){
if( i!=0 ) if( i!=0 )
ret.append( '\n' ); ret.append( '\n' );
if( prefix.length() > 0 ) if( prefix.length() > 0 )
ret.append( prefix ); ret.append( prefix );
ret.append( array[i] ); ret.append( array[i] );
} }
ret.append( '\n' ); ret.append( '\n' );
} }
return ret.toString(); return ret.toString();
} }
/** /**
* If the formatter should add a time stamp in front of the log message * If the formatter should add a time stamp in front of the log message
* *
* @param enable set to True to activate time stamp * @param enable set to True to activate time stamp
*/ */
public void enableTimeStamp(boolean enable){ public void enableTimeStamp(boolean enable){
timeStamp = enable; timeStamp = enable;
} }
/** /**
* The DateFormat to print in the time stamp * The DateFormat to print in the time stamp
* *
* @param ts is the String to send to SimpleDateFormat * @param ts is the String to send to SimpleDateFormat
*/ */
public void setTimeStamp(String ts){ public void setTimeStamp(String ts){
dateFormatter = new SimpleDateFormat(ts); dateFormatter = new SimpleDateFormat(ts);
} }
/** /**
* If the formatter should add the class/source name in front of the log message * 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 * @param enable set to True to activate class/source name
*/ */
public void enableClassName(boolean enable){ public void enableClassName(boolean enable){
className = enable; className = enable;
} }
/** /**
* If the formatter should add the class/source name in front of the log message * 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 * @param enable set to True to activate class/source name
*/ */
public void enableMethodName(boolean enable){ public void enableMethodName(boolean enable){
methodName = enable; methodName = enable;
} }
/** /**
* @return the Class name * @return the Class name
*/ */
private String paddClassName(String source){ private String paddClassName(String source){
String cStr = padd_cache.get(source); String cStr = padd_cache.get(source);
if (cStr == null || cStr.length() != max_class_name) { if (cStr == null || cStr.length() != max_class_name) {
cStr = source.substring(source.lastIndexOf('.') + 1); // Remove packages cStr = source.substring(source.lastIndexOf('.') + 1); // Remove packages
if (cStr.lastIndexOf('$') >= 0) { // extract subclass name if (cStr.lastIndexOf('$') >= 0) { // extract subclass name
String subClass = cStr.substring(cStr.lastIndexOf('$') + 1); String subClass = cStr.substring(cStr.lastIndexOf('$') + 1);
if (!Pattern.matches("\\d+", subClass)) // Don'n substring for anonymous classes if (!Pattern.matches("\\d+", subClass)) // Don'n substring for anonymous classes
cStr = subClass; cStr = subClass;
} }
if (cStr.length() > max_class_name) if (cStr.length() > max_class_name)
max_class_name = cStr.length(); max_class_name = cStr.length();
cStr += StringUtil.getSpaces(max_class_name - cStr.length()); cStr += StringUtil.getSpaces(max_class_name - cStr.length());
padd_cache.put(source, cStr); padd_cache.put(source, cStr);
} }
return cStr; return cStr;
} }
} }

View file

@ -37,95 +37,95 @@ import java.util.logging.*;
* @author Ziver * @author Ziver
*/ */
public class LogUtil { 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 * @return a new Logger for the calling class
*/ */
public static Logger getLogger(){ public static Logger getLogger(){
return Logger.getLogger(ClassUtil.getCallingClass(LogUtil.class)); return Logger.getLogger(ClassUtil.getCallingClass(LogUtil.class));
} }
/** /**
* Sets the log formatter to all root Handlers * Sets the log formatter to all root Handlers
* *
* @param f is the formatter class * @param f is the formatter class
*/ */
public static void setGlobalFormatter(Formatter f){ public static void setGlobalFormatter(Formatter f){
Logger root = Logger.getLogger(""); Logger root = Logger.getLogger("");
for (Handler handler : root.getHandlers()) { for (Handler handler : root.getHandlers()) {
handler.setFormatter(f); handler.setFormatter(f);
} }
} }
/** /**
* Adds the log formatter to all handlers in the namespace * Adds the log formatter to all handlers in the namespace
* *
* @param f is the formatter class * @param f is the formatter class
*/ */
public static void setFormatter(String name, Formatter f){ public static void setFormatter(String name, Formatter f){
Logger root = Logger.getLogger(name); Logger root = Logger.getLogger(name);
for (Handler handler : root.getHandlers()) { for (Handler handler : root.getHandlers()) {
handler.setFormatter(f); handler.setFormatter(f);
} }
} }
/** /**
* Sets the global log level * Sets the global log level
*/ */
public static void setGlobalLevel(Level level){ public static void setGlobalLevel(Level level){
setLevel("", level); setLevel("", level);
} }
/** /**
* Adds a Handler to the root namespace * Adds a Handler to the root namespace
*/ */
public static void addGlobalHandler(Handler handler){ public static void addGlobalHandler(Handler handler){
Logger root = Logger.getLogger(""); Logger root = Logger.getLogger("");
root.addHandler(handler); root.addHandler(handler);
} }
/** /**
* Sets the log level for a specified class * Sets the log level for a specified class
*/ */
public static void setLevel(Class<?> c, Level level){ public static void setLevel(Class<?> c, Level level){
setLevel(c.getName(), level); setLevel(c.getName(), level);
} }
/** /**
* Sets the log level for a specified logger * Sets the log level for a specified logger
*/ */
public static void setLevel(String name, Level level){ public static void setLevel(String name, Level level){
logger.fine("Changing log level of \""+name+"\" to \""+level.getLocalizedName()+"\""); logger.fine("Changing log level of \""+name+"\" to \""+level.getLocalizedName()+"\"");
Logger newLogger = Logger.getLogger(name); Logger newLogger = Logger.getLogger(name);
newLogger.setLevel(level); newLogger.setLevel(level);
// Check if the logger has a handler // Check if the logger has a handler
if( newLogger.getHandlers().length > 0 ){ if( newLogger.getHandlers().length > 0 ){
// Set the level on the handlers if its level is higher // Set the level on the handlers if its level is higher
for (Handler handler : newLogger.getHandlers()) { for (Handler handler : newLogger.getHandlers()) {
if(handler.getLevel().intValue() > level.intValue()) if(handler.getLevel().intValue() > level.intValue())
handler.setLevel(level); handler.setLevel(level);
} }
} }
} }
public static boolean isLoggable(Class clazz, Level level){ public static boolean isLoggable(Class clazz, Level level){
return Logger.getLogger(clazz.getName()).isLoggable(level); return Logger.getLogger(clazz.getName()).isLoggable(level);
} }
public static void readConfiguration(String file){ public static void readConfiguration(String file){
try{ try{
File confFile = FileUtil.find(file); File confFile = FileUtil.find(file);
if (confFile != null) { if (confFile != null) {
FileInputStream in = new FileInputStream(confFile); FileInputStream in = new FileInputStream(confFile);
LogManager.getLogManager().readConfiguration(in); LogManager.getLogManager().readConfiguration(in);
in.close(); in.close();
} }
else else
logger.warning("Unable to find logging configuration file: "+file); logger.warning("Unable to find logging configuration file: "+file);
} catch (Exception e){ } catch (Exception e){
logger.log(Level.SEVERE, "Unable to load logging configuration: "+file, 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{ public class NetLogClient extends Thread{
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
private ConcurrentLinkedQueue<NetLogListener> listeners; private ConcurrentLinkedQueue<NetLogListener> listeners;
private Socket s; private Socket s;
private ObjectOutputStream out; private ObjectOutputStream out;
public NetLogClient(String host, int port) throws UnknownHostException, IOException{ public NetLogClient(String host, int port) throws UnknownHostException, IOException{
s = new Socket(host, port); s = new Socket(host, port);
out = new ObjectOutputStream(s.getOutputStream()); out = new ObjectOutputStream(s.getOutputStream());
listeners = new ConcurrentLinkedQueue<NetLogListener>(); listeners = new ConcurrentLinkedQueue<NetLogListener>();
this.start(); this.start();
} }
public void addListener(NetLogListener listener){ public void addListener(NetLogListener listener){
logger.info("Registring new NetLogListener: "+listener.getClass().getName()); logger.info("Registring new NetLogListener: "+listener.getClass().getName());
listeners.add( listener ); listeners.add( listener );
} }
public void run(){ public void run(){
try{ try{
ObjectInputStream in = new ObjectInputStream(s.getInputStream()); ObjectInputStream in = new ObjectInputStream(s.getInputStream());
while( true ){ while( true ){
Object o = in.readObject(); Object o = in.readObject();
for( NetLogListener listener : listeners ){ for( NetLogListener listener : listeners ){
if( o instanceof NetLogMessage ) if( o instanceof NetLogMessage )
listener.handleLogMessage((NetLogMessage)o); listener.handleLogMessage((NetLogMessage)o);
else if( o instanceof NetLogExceptionMessage ) else if( o instanceof NetLogExceptionMessage )
listener.handleExceptionMessage((NetLogExceptionMessage)o); listener.handleExceptionMessage((NetLogExceptionMessage)o);
else if( o instanceof NetLogStatusMessage ) else if( o instanceof NetLogStatusMessage )
listener.handleStatusMessage((NetLogStatusMessage)o); listener.handleStatusMessage((NetLogStatusMessage)o);
else else
logger.warning("Received unknown message: "+o.getClass().getName()); logger.warning("Received unknown message: "+o.getClass().getName());
} }
} }
} catch( Exception e ){ } catch( Exception e ){
logger.log(Level.SEVERE, null, e); logger.log(Level.SEVERE, null, e);
close(); close();
} }
} }
public void close(){ public void close(){
try{ try{
this.interrupt(); this.interrupt();
s.close(); s.close();
} catch (Exception e){ } catch (Exception e){
logger.log(Level.SEVERE, "Unable to close Client Socket.", 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; import java.util.logging.LogRecord;
public class NetLogExceptionMessage implements Message { public class NetLogExceptionMessage implements Message {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private int count; private int count;
private String name; private String name;
private String message; private String message;
private String stackTrace; private String stackTrace;
NetLogExceptionMessage(String name, String message, String stackTrace){ NetLogExceptionMessage(String name, String message, String stackTrace){
this.count = 1; this.count = 1;
this.name = name; this.name = name;
this.message = message; this.message = message;
this.stackTrace = stackTrace; this.stackTrace = stackTrace;
} }
public NetLogExceptionMessage(LogRecord record) { public NetLogExceptionMessage(LogRecord record) {
Throwable exception = record.getThrown(); Throwable exception = record.getThrown();
this.count = 1; this.count = 1;
this.name = exception.getClass().getName(); this.name = exception.getClass().getName();
this.message = exception.getMessage(); this.message = exception.getMessage();
this.stackTrace = ""; this.stackTrace = "";
for(int i=0; i<exception.getStackTrace().length; i++){ for(int i=0; i<exception.getStackTrace().length; i++){
this.stackTrace += exception.getStackTrace()[i].toString(); this.stackTrace += exception.getStackTrace()[i].toString();
} }
} }
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((message == null) ? 0 : message.hashCode()); result = prime * result + ((message == null) ? 0 : message.hashCode());
result = prime * result result = prime * result
+ ((stackTrace == null) ? 0 : stackTrace.hashCode()); + ((stackTrace == null) ? 0 : stackTrace.hashCode());
return result; return result;
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) if (this == obj)
return true; return true;
if (obj == null || getClass() != obj.getClass()) if (obj == null || getClass() != obj.getClass())
return false; return false;
NetLogExceptionMessage other = (NetLogExceptionMessage) obj; NetLogExceptionMessage other = (NetLogExceptionMessage) obj;
if (name.equals(other.name) && message.equals(other.message) && if (name.equals(other.name) && message.equals(other.message) &&
stackTrace.equals(other.stackTrace)) { stackTrace.equals(other.stackTrace)) {
return true; return true;
} }
return false; return false;
} }
public void addCount(int add){ public void addCount(int add){
count += add; count += add;
} }
public int getCount() { public int getCount() {
return count; return count;
} }
public String getName() { public String getName() {
return name; return name;
} }
public String getMessage() { public String getMessage() {
return message; return message;
} }
public String getStackTrace() { public String getStackTrace() {
return stackTrace; return stackTrace;
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -42,26 +42,26 @@ import static zutil.net.http.multipart.MultipartParser.HEADER_CONTENT_TYPE;
public class MultipartFileField implements MultipartField{ public class MultipartFileField implements MultipartField{
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
private String fieldname; private String fieldname;
private String filename; private String filename;
private String contentType; private String contentType;
private byte[] content; private byte[] content;
private InputStream in; private InputStream in;
protected MultipartFileField(Map<String,String> headers, InputStream in) throws IOException { protected MultipartFileField(Map<String,String> headers, InputStream in) throws IOException {
this.fieldname = headers.get("name"); this.fieldname = headers.get("name");
this.filename = headers.get("filename"); this.filename = headers.get("filename");
this.contentType = headers.get(HEADER_CONTENT_TYPE); this.contentType = headers.get(HEADER_CONTENT_TYPE);
this.in = in; this.in = in;
} }
/** /**
* @return the amount of data received for this field * @return the amount of data received for this field
*/ */
public long getLength(){ public long getLength(){
return 0; //TODO: return 0; //TODO:
} }
/** /**
* @return the field name * @return the field name
@ -70,13 +70,13 @@ public class MultipartFileField implements MultipartField{
return fieldname; return fieldname;
} }
public String getFilename(){ public String getFilename(){
return filename; return filename;
} }
public String getContentType() { public String getContentType() {
return contentType; 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 * Note: Only one of the methods {@link #getContent()} or
* {@link #saveToFile(File)} can be used as they will consume the data in the stream. * {@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 * @param file is the new file where the data will be stored
*/ */
public void saveToFile(File file) throws IOException { public void saveToFile(File file) throws IOException {
if (in == null) if (in == null)
throw new IOException("Stream already consumed."); throw new IOException("Stream already consumed.");
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file)); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
IOUtil.copyStream(in, out); IOUtil.copyStream(in, out);
out.close(); out.close();
in = null; // reset InputStream 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_DISPOSITION = "Content-Disposition".toUpperCase();
protected static final String HEADER_CONTENT_TYPE = "Content-Type".toUpperCase(); protected static final String HEADER_CONTENT_TYPE = "Content-Type".toUpperCase();
/** This is the delimiter that will separate the fields */ /** This is the delimiter that will separate the fields */
private String delimiter; private String delimiter;
/** The length of the HTTP Body */ /** The length of the HTTP Body */
private long contentLength; private long contentLength;
/** This is the input stream */ /** This is the input stream */
private InputStream in; private InputStream in;
private MultiPartIterator iterator; private MultiPartIterator iterator;
@ -66,11 +66,11 @@ public class MultipartParser implements Iterable<MultipartField>{
this.delimiter = delimiter; this.delimiter = delimiter;
this.contentLength = length; this.contentLength = length;
} }
public MultipartParser(HttpHeader header){ public MultipartParser(HttpHeader header){
this(header.getInputStream(), this(header.getInputStream(),
parseDelimiter(header.getHeader("Content-type")), parseDelimiter(header.getHeader("Content-type")),
Long.parseLong(header.getHeader("Content-Length"))); Long.parseLong(header.getHeader("Content-Length")));
} }
private static String parseDelimiter(String contentTypeHeader){ private static String parseDelimiter(String contentTypeHeader){
String delimiter = contentTypeHeader.split(" *; *")[1]; String delimiter = contentTypeHeader.split(" *; *")[1];
@ -78,18 +78,18 @@ public class MultipartParser implements Iterable<MultipartField>{
return delimiter; return delimiter;
} }
public long getContentLength(){ public long getContentLength(){
return contentLength; return contentLength;
} }
@Override @Override
public Iterator<MultipartField> iterator() { public Iterator<MultipartField> iterator() {
if (iterator == null) if (iterator == null)
iterator = new MultiPartIterator(); iterator = new MultiPartIterator();
return iterator; return iterator;
} }
protected class MultiPartIterator implements Iterator<MultipartField>{ protected class MultiPartIterator implements Iterator<MultipartField>{

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -26,33 +26,33 @@ package zutil.net.nio.response;
// TODO: this class has a strange structure, should be refactored // TODO: this class has a strange structure, should be refactored
public abstract class ResponseHandler { public abstract class ResponseHandler {
private Object rsp = null; private Object rsp = null;
public synchronized void handleResponse(Object rsp) { public synchronized void handleResponse(Object rsp) {
this.rsp = rsp; this.rsp = rsp;
responseEvent(rsp); responseEvent(rsp);
notify(); notify();
} }
/** /**
* Blocks the calling thread until there is a response * Blocks the calling thread until there is a response
*/ */
public void waitForResponse() { public void waitForResponse() {
while(!gotResponse()) { while(!gotResponse()) {
try { try {
synchronized (this) { synchronized (this) {
this.wait(); this.wait();
} }
} catch (InterruptedException e) {} } catch (InterruptedException e) {}
} }
} }
/** /**
* @return true if a response has been received * @return true if a response has been received
*/ */
public boolean gotResponse(){ public boolean gotResponse(){
return (rsp != null); 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; import zutil.net.nio.message.EchoMessage;
public class StringResponseMessage extends EchoMessage implements RequestResponseMessage { public class StringResponseMessage extends EchoMessage implements RequestResponseMessage {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private long responseId; private long responseId;
private String msg; private String msg;
public StringResponseMessage(String msg){ public StringResponseMessage(String msg){
this.msg = msg; this.msg = msg;
responseId = (long)(Math.random()*Long.MAX_VALUE); responseId = (long)(Math.random()*Long.MAX_VALUE);
} }
public long getResponseId() { public long getResponseId() {
return responseId; return responseId;
} }
public void setString(String msg){ public void setString(String msg){
this.msg = msg; this.msg = msg;
} }
public String toString(){ public String toString(){
return msg; return msg;
} }
} }

View file

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

View file

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

View file

@ -40,29 +40,29 @@ import java.util.logging.Logger;
public class StandardWorker extends ThreadedEventWorker { public class StandardWorker extends ThreadedEventWorker {
private static Logger logger = LogUtil.getLogger(); private static Logger logger = LogUtil.getLogger();
private NioNetwork nio; private NioNetwork nio;
// Maps a responseId to a RspHandler // Maps a responseId to a RspHandler
private Map<Long, ResponseHandler> rspEvents = new HashMap<>(); private Map<Long, ResponseHandler> rspEvents = new HashMap<>();
// Different services listening on specific messages // Different services listening on specific messages
private Map<Class<?>, ThreadedEventWorker> services = new HashMap<>(); private Map<Class<?>, ThreadedEventWorker> services = new HashMap<>();
/** /**
* Creates a new StandardWorker * Creates a new StandardWorker
*/ */
public StandardWorker(NioNetwork nio){ public StandardWorker(NioNetwork nio){
this.nio = nio; this.nio = nio;
} }
@Override @Override
public void messageEvent(WorkerEventData event) { public void messageEvent(WorkerEventData event) {
try { try {
logger.finer("Message: "+event.data.getClass().getName()); logger.finer("Message: "+event.data.getClass().getName());
if(event.data instanceof EchoMessage && !((EchoMessage)event.data).echo()){ if(event.data instanceof EchoMessage && !((EchoMessage)event.data).echo()){
// Echo back the received message // Echo back the received message
@ -86,29 +86,29 @@ public class StandardWorker extends ThreadedEventWorker {
services.get(event.data.getClass()).messageEvent(event); services.get(event.data.getClass()).messageEvent(event);
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
/** /**
* Maps a Worker to a specific message * 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
*
* @param messageClass the received message class * @param messageClass the received message class
*/ * @param worker the worker that should handle the specified message type
public void unregisterWorker(Class<?> messageClass){ */
services.remove(messageClass); 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 * Send a message with a defined response handler
@ -117,10 +117,10 @@ public class StandardWorker extends ThreadedEventWorker {
* @param message the message object * @param message the message object
* @param handler the handler that should be called when a response is received * @param handler the handler that should be called when a response is received
*/ */
public void send(SocketAddress address, RequestResponseMessage message, ResponseHandler handler) throws IOException { public void send(SocketAddress address, RequestResponseMessage message, ResponseHandler handler) throws IOException {
// Register the response handler // Register the response handler
rspEvents.put(message.getResponseId(), 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; package zutil.net.nio.worker;
public abstract class ThreadedEventWorker extends Worker implements Runnable{ public abstract class ThreadedEventWorker extends Worker implements Runnable{
private Thread thread; private Thread thread;
public ThreadedEventWorker(){ public ThreadedEventWorker(){
thread = new Thread(this); thread = new Thread(this);
thread.start(); thread.start();
} }
public void run() { public void run() {
while(true) { while(true) {
try{ try{
// Wait for data to become available // Wait for data to become available
messageEvent(pollEvent()); messageEvent(pollEvent());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); 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 { 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) { public void processData(NioNetwork server, SocketAddress remote, Object data) {
synchronized(queue) { synchronized(queue) {
queue.add(new WorkerEventData(server, remote, data)); queue.add(new WorkerEventData(server, remote, data));
queue.notify(); queue.notify();
} }
} }
/** /**
* @return true if there is a event in the queue * @return true if there is a event in the queue
*/ */
protected boolean hasEvent(){ protected boolean hasEvent(){
return !queue.isEmpty(); return !queue.isEmpty();
} }
/** /**
* Polls a event from the list or blocks until there is a event available * Polls a event from the list or blocks until there is a event available
* *
* @return the next event * @return the next event
*/ */
protected WorkerEventData pollEvent(){ protected WorkerEventData pollEvent(){
synchronized(queue) { synchronized(queue) {
while (queue.isEmpty()) { while (queue.isEmpty()) {
try { try {
queue.wait(); queue.wait();
} catch (InterruptedException e) {} } catch (InterruptedException e) {}
} }
} }
return queue.poll(); return queue.poll();
} }
} }

View file

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

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