Wednesday, 12 March 2008

Hangman with Generics

I'm implementing a hangman game, which uses a HashMap to store a character and result of the character guess.


public abstract class Guess{}

public class CorrectGuess extends Guess{}

public class FailedGuess extends Guess{}

public class Hangman {
private Map<Character,Guess> state = new HashMap<Character,Guess>();
}


I want to be able to get a list of the various correct and failed guesses, so the details can be displayed.

The nasty solution i've currently got is to use "instanceof", but i feel this misses the point of using generics.


// the calling code looks something like
void display()
{
hangmanDisplay.display(getFailedGuesses());
consoleDisplay.display(getCorrectGuesses());
}

public List<CorrectGuess> getCorrectGuesses()
{
List<CorrectGuess> list = new ArrayList<CorrectGuess>(secret.length());
for(Iterator iterator = state.values().iterator();iterator.hasNext();)
{
Guess guess = (Guess) iterator.next();
if(guess instanceof CorrectGuess)
list.add((CorrectGuess)guess);
}
return list;
}

public List<FailedGuess> getFailedGuesses()
{...}


I want to be able to use the generic parameter type to control what is added to the list.


// the calling code would then look something like
void display()
{
hangmanDisplay.display(getGuesses(new ArrayList<FailedGuess>()));
consoleDisplay.display(getGuesses(new ArrayList<CorrectGuess>());
}

/**
* get all values of generic parameter type T in the HashSet and add to the list.
*/
public void getGuesses(List<? super Guess> list)
{
state,values().iterator();
// how can i compare the type thats in the iterator.next() with the type defined by T in the input parameter?
}

Java Generics

I think the The Craftsman 44: Java Generics 2 gives the best exaplaination on when to use extends or super when defining Generics.

Basically use

you can widen the type of a list by using ? extends X, only if you
plan on reading from that list

and

If you plan on writing to that list, use

Tuesday, 11 March 2008

The Open Closed Principle

The Open Closed Principle says that you should design modules that never change. When requirements change, you extend the behavior of such modules by adding new code, not by changing old code that already works.

Monday, 18 February 2008

Sunday 17th Feb

Naas - Kill - Brittas - NewTownMountKennedy - Blessinton - Naas [45km]



View Larger Map

Thursday, 14 February 2008

SVN KIT API


package com.xx;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

public class FileSvnInfo
{
Log log = LogFactory.getLog(FileSvnInfo.class);

/*
* Default values:
*/
String url = "http://proddev-svn/svn/norkom/Prototypes/Ref2_Transliteration/trunk";
String name = "xx";
String password = "xx";
String filePath = "changelog.txt";

public FileSvnInfo()
{
SVNRepository repository = createSVNRepository();
log.info(createSVNRepository().getLocation().toString());

getFileInfo(repository,"changelog.txt");
getFileInfo(repository,"./Engineering");

}

private void getFileInfo(SVNRepository repository, String filePath)
{
try
{
SVNNodeKind kind = repository.checkPath(filePath, -1);
if(kind.equals(SVNNodeKind.FILE))
log.info(SVNNodeKind.FILE+" "+filePath);
else if(kind.equals(SVNNodeKind.DIR))
log.info(SVNNodeKind.DIR+" "+filePath);
else if(kind.equals(SVNNodeKind.NONE))
log.info(SVNNodeKind.NONE+" "+filePath);
else if(kind.equals(SVNNodeKind.UNKNOWN))
log.info(SVNNodeKind.UNKNOWN+" "+filePath);
}
catch(SVNException e)
{
e.printStackTrace();
}
}

private SVNRepository createSVNRepository()
{
SVNRepository repository = null;
try {
/*
* Creates an instance of SVNRepository to work with the repository.
* All user's requests to the repository are relative to the
* repository location used to create this SVNRepository.
* SVNURL is a wrapper for URL strings that refer to repository locations.
*/
repository = SVNRepositoryFactory.create(SVNURL.parseURIEncoded(url));
} catch (SVNException svne) {
/*
* Perhaps a malformed URL is the cause of this exception
*/
System.err
.println("error while creating an SVNRepository for the location '"
+ url + "': " + svne.getMessage());
System.exit(1);
}

ISVNAuthenticationManager authManager =
SVNWCUtil.createDefaultAuthenticationManager(name, password);
repository.setAuthenticationManager(authManager);

return repository;
}

private static void setupLibrary()
{
/*
* For using over http:// and https://
*/
DAVRepositoryFactory.setup();
/*
* For using over svn:// and svn+xxx://
*/
//SVNRepositoryFactoryImpl.setup();

/*
* For using over file:///
*/
FSRepositoryFactory.setup();
}

/**
* @param args
*/
public static void main(String[] args)
{
setupLibrary();
new FileSvnInfo();
}
}

Saturday, 9 February 2008

Saturday 9th Feb 2008


HC - Glencullen - Kilmalin - Rossbrook - HC


View Larger Map

Tuesday, 5 February 2008

NTLM with Firefox

Here are the steps to make sure Firefox supports NTML authentication:

  • Type "about:config" in the address bar,
  • In the Filter, type in "ntlm".  This should make the "network.automatic-ntlm-auth.trusted-uris" property appear,
  • Add ".you.required.url"

It should allow you to use Firefox to access the service.