Thursday, March 3, 2011

Overriding hash code and equals in collections


package SDMXDatabaseUploader;

import java.util.HashMap;


public class SDMXSeries {
public HashMap SeriesKey = new HashMap();

public HashMap Obs = new HashMap();
/**
* Since SeriesKeys have to be unique this is
* what defines if an SDMXSeries equals another.
*/

public boolean equals(Object o){
SDMXSeries comparison = (SDMXSeries)o;
return SeriesKey.equals(comparison.SeriesKey);

}
/**
*
*/
public int hashCode(){
return SeriesKey.hashCode();

}

/**
*
* @param key
* @param value
* @throws NullPointerException if key or value is null.
* @throws DuplicateKeyException if key is repeated.
*/
public void addSeriesKeyValue(String key, String value)throws NullPointerException, DuplicateKeyException{

if (key == null || value == null)throw new NullPointerException("Key or Value is null");
if (SeriesKey.containsKey(key))throw new DuplicateKeyException("Failed trying to add a duplicate key to the series key" + key);
SeriesKey.put(key, value);

}
/**
*
* @param key
* @param value
* @throws NullPointerException if key or value is null.
* @throws DuplicateKeyException if key is repeated.
*/
public void addObsKeyValue(String key, String value)throws NullPointerException, DuplicateKeyException{

if (key == null || value == null)throw new NullPointerException("Key or Value is null");
if (Obs.containsKey(key))throw new DuplicateKeyException("Failed Trying to add a duplicate key to the series key" + key);
Obs.put(key, value);
}
public String toString(){
return SeriesKey.toString() + " " + Obs.toString();

}
}


Exception code...


package SDMXDatabaseUploader;

public class DuplicateKeyException extends Exception {

/**
*
*/
private static final long serialVersionUID = 1L;
public DuplicateKeyException (String message){
super(message);
}
public DuplicateKeyException (){
super("Failed attempting to add duplicate key.");

}

}

package SDMXDatabaseUploader;

public class EmptyValueException extends Exception {
public EmptyValueException (int lineNumber){
super("Processed Line "+ lineNumber +"has an empty string for one or more entries.");
}

}

Crypto Utils

This is taken directly from http://www.rgagnon.com/javadetails/java-0400.html


It is wholly this persons work and what follows is a copy for my future reference...

package SDMXDatabaseUploader;
/*
* Taken directly with thanks from http://www.rgagnon.com/javadetails/java-0400.html
*/
import java.io.File;
import java.io.FileWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class CryptoUtils {

public static final String AES = "AES";

/**
* encrypt a value and generate a keyfile
* if the keyfile is not found then a new one is created
* @throws GeneralSecurityException
* @throws IOException
*/
public static String encrypt(String value, File keyFile)
throws GeneralSecurityException, IOException
{
if (!keyFile.exists()) {
KeyGenerator keyGen = KeyGenerator.getInstance(CryptoUtils.AES);
keyGen.init(128);
SecretKey sk = keyGen.generateKey();
FileWriter fw = new FileWriter(keyFile);
fw.write(byteArrayToHexString(sk.getEncoded()));
fw.flush();
fw.close();
}

SecretKeySpec sks = getSecretKeySpec(keyFile);
Cipher cipher = Cipher.getInstance(CryptoUtils.AES);
cipher.init(Cipher.ENCRYPT_MODE, sks, cipher.getParameters());
byte[] encrypted = cipher.doFinal(value.getBytes());
return byteArrayToHexString(encrypted);
}

/**
* decrypt a value
* @throws GeneralSecurityException
* @throws IOException
*/
public static String decrypt(String message, File keyFile)
throws GeneralSecurityException, IOException
{
SecretKeySpec sks = getSecretKeySpec(keyFile);
Cipher cipher = Cipher.getInstance(CryptoUtils.AES);
cipher.init(Cipher.DECRYPT_MODE, sks);
byte[] decrypted = cipher.doFinal(hexStringToByteArray(message));
return new String(decrypted);
}



private static SecretKeySpec getSecretKeySpec(File keyFile)
throws NoSuchAlgorithmException, IOException
{
byte [] key = readKeyFile(keyFile);
SecretKeySpec sks = new SecretKeySpec(key, CryptoUtils.AES);
return sks;
}

private static byte [] readKeyFile(File keyFile)
throws FileNotFoundException
{
Scanner scanner =
new Scanner(keyFile).useDelimiter("\\Z");
String keyValue = scanner.next();
scanner.close();
return hexStringToByteArray(keyValue);
}


private static String byteArrayToHexString(byte[] b){
StringBuffer sb = new StringBuffer(b.length * 2);
for (int i = 0; i < b.length; i++){
int v = b[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}

private static byte[] hexStringToByteArray(String s) {
byte[] b = new byte[s.length() / 2];
for (int i = 0; i < b.length; i++){
int index = i * 2;
int v = Integer.parseInt(s.substring(index, index + 2), 16);
b[i] = (byte)v;
}
return b;
}

}

Calling code

package JUnitTests;

import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;

import SDMXDatabaseUploader.CryptoUtils;
import junit.framework.Assert;
import junit.framework.TestCase;

public class CryptoUtilsTest extends TestCase {
public void testCrypto(){
final String KEY_FILE = "./src/crypto.key";
//final String PWD_FILE = "c:/temp/howto.properties";

String clearPwd= "JUnitTestPassword";

// Properties p1 = new Properties();

//p1.put("user", "Real");
String encryptedPwd = null;
try {
encryptedPwd = CryptoUtils.encrypt(clearPwd, new File(KEY_FILE));
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//p1.put("pwd", encryptedPwd);
// p1.store(new FileWriter(PWD_FILE), "");

// ==================
//Properties p2 = new Properties();

//p2.load(new FileReader(PWD_FILE));
//encryptedPwd = p2.getProperty("pwd");
//System.out.println(encryptedPwd);
try {
//System.out.println
// (CryptoUtils.decrypt(encryptedPwd, new File(KEY_FILE)));
Assert.assertEquals("Encryption Failed", CryptoUtils.decrypt(encryptedPwd, new File(KEY_FILE)), clearPwd);
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}