Überprüfen ESR Referenz-Nummer

Mir wurde die Aufgabe gestellt, eine Prüfroutine für die ESR-Referenz zu implementieren – in Java. Nach einem Fehlstart duch das Verwenden des falschen Algorithmus (Luhn Algorithmus zur Modulo 10 Prüfung) habe ich den Richtigen gefunden. Jedoch nur für C/C++, Visual Basic und PHP. Auf dieser Basis war es mir dann möglich eine Adaption für Java zu bilden „Überprüfen ESR Referenz-Nummer“ weiterlesen

Generieren einer Landschaft

Seit längerem versuche ich einen vernünftigen Algorithmus zu entwickeln, um eine binäre Landschaft zu erzeugen. Binär daher, da ich wissen möchte was ist Land und was ist Meer. Eine reine Zufallsverteilung führt dazu dass viele kleine „Inseln“ entstehen. Dies bedeutet, dass bei der Entscheidung ob ein Feld Wasser oder Land ist eine Gewichtung einfliessen muss. Diese Gewichtung muss dazuführen, dass sich gleich zu gleich gesellt. „Generieren einer Landschaft“ weiterlesen

Eigene Objekte in Javascript

Die Definietion von eigenen Objekten in JavaScript alla

var myObject = {
  eigenschaft:"",
  methode: function(){
    ...
  }
}

ist eine tolle Sache. Insbesondere wenn aber die Objekte grösser und komplexer als obiges werden kann dies zu Problemen führen, für die der Internet Explorer besonders anfällig ist. So sagt er zum Beispiel das Object ist undefined. Eine mögliche Ursache kann ein ‚,‘ zu viel sein. Zwischen den äussersten geschweiften Klammern werden variablen und Funktionen aufgelistet. Nach dem letzten „Listeneintrag“ darf kein ‚,‘ folgen. Weiters zeigt sich, dass der IE bei grösseren Objekten in oben beschriebener schreibweise das Objekt ebenfalls nicht kennt. Hier hilft es, das Objekt etwas anders zu definieren:

var myObject = {
  eigenschaft:"",
  methode: function(){
    ...
  }
}
myObject.methode2 = function(){
...
}
myObject.methode3 = function(){
...
}

Beim dynamischen Erstellen von Knoten habe ich zudem festgestellt, dass der IE gewisse Zeichenfolgen als geschützte Zeichenketten behandelt:

class = document.createAttribute('class');

ist zwar zulässig, führt jedoch im IE zu einem Abbruch; für add trift selbiges zu. Es kann auch vorkommen, dass der IE ein Attribut Knoten einem Knoten nicht zufügen will. Dies lässt sich umgehen indem man statt:

size = document.createAttribute('size');
size.nodeValue='100';
input.setAttributeNode(size);
name = document.createAttribute(document.createAttribute('size'));
name.setAttribute('size','100');

verwendet.
Versucht man einen Knoten mit einem Event-Listener dynamisch zu generieren,

<input id="esrscan" class="xg" onkeydown="listenEnter(event);" name="ESRSCAN" size="100" type="text"/>

Wird die Methode im IE nicht ausgeführt. Hier hilft nur, den Code-Block bereits im HTML-Code zu halten und das Element mittels

document.forms[0].elements["ESRSCAN"].display="none";

verstecken. Anstelle des generieren kann das Element dann eingeblendet werden ( Setzte das display attribute auch ‚block‘).
Eine Ausführliche Anleitung zum erstellen von eigenen Objekten in JavaScript ist bei SelfHTML zu finden.

Durchsuchen des Classpath

Das JDK bringt von Haus aus bereits ein mächtiges Framework mit sich, mit dem sich zur Runtime Informationen über die Applikation gewinnen lassen, wie auch schon in einem früheren Beitrag beschrieben. Dies funktioniert solange einwandfrei als ich weiss auf welche Klasse ich die Reflection los lasse.
Mit Annotation lässt sich eine Vielzahl von Dingen bewerkstelligen, so kann man auch auf den Gedanken verfallen, dass man Bestimmte Aufgaben definiert (beispielsweise in einer Enumeration). Die Ausführung dieser Aufgaben übernehmen Methoden mit einer nicht näher bekannten Signatur. Was aber bekannt ist, ist dass die Methode mit einer Annotation gekennzeichnet ist, die besagt, dass diese Methode jene Aufgabe erfüllt.
Wie gelange ich nun an die Klasse in der die Methode definiert ist? Nur mit dem JDK ist dies nicht möglich. Dazu müssen aus dem Classpath alle Klassen ausgelesen werden. Dann kann jede einzelne Klasse nach der Methode untersucht werden, die die spezifizierte Annotation besitzt.
Wem dies alles etwas zu abstrakt war hier das Beispiel:

public class ClassFinder {
        /**
         * Defined classpath
         */
	private static final String CLASSPATH = System.getProperty("java.class.path");
	/**
	 * List with the jar files on the classpath
	 */
	private static String[] jarFiles;
	/**
	 * List with the directories on the classpath (containing .class files)
	 */
	private static String[] binDirs;
	/**
	 * All Classpath elements
	 */
	private static File[] classPathDirs = null;
	/**
	 * Default constructur initializes the directories indicated by the
	 * CLASSPATH, if they are not yet initialized.
	 */
	public ClassFinder() {
		if (classPathDirs == null) {
			initClassPathDir();
		}
	}
	/**
	 * Initialize the directories based on the classpath
	 */
	private void initClassPathDir() {
		StringTokenizer st = new StringTokenizer(CLASSPATH, File.pathSeparator);
		int count = st.countTokens();
		classPathDirs = new File[count];
		Vector jar = new Vector();
		Vector bin = new Vector();
		for (int i = 0; i < count; i++) {
			classPathDirs[i] = new File(st.nextToken());
			if (classPathDirs[i].isDirectory()) {
				bin.add(classPathDirs[i].getAbsolutePath());
			} else {
				jar.add(classPathDirs[i].getAbsolutePath());
			}
		}
		jarFiles = new String[jar.size()];
		binDirs = new String[bin.size()];
		jar.copyInto(jarFiles);
		bin.copyInto(binDirs);
	}

	/**
	 * Retrive all classes of the indicated package. The package is searched in
	 * all classpath directories that are directories
	 * 
	 * @param packageName
	 *            name of the package as 'ch.sahits.civ'
	 * @return Array of found classes
	 * @throws ClassNotFoundException
	 */
	public Class[] getAll(String packageName) throws ClassNotFoundException {
		String packageDir = convertPackege(packageName);
		Vector classes = new Vector();
		for (int i = 0; i < binDirs.length; i++) {
			packageDir = binDirs[i] + File.separator + packageDir;
			File dir = new File(packageDir);
			classes.addAll(extractClasses(packageName, dir));
		}
		Class[] result = new Class[classes.size()];
		classes.copyInto(result);
		return result;
	}
	/**
	 * Extract all the classes from a directory
	 * @param packageName name of the package as 'ch.sahits.civ'
	 * @param dir Package as directory
	 * @return Vector with all found directories
	 * @throws ClassNotFoundException
	 */
	private Vector extractClasses(String packageName, File dir) throws ClassNotFoundException {
		Vector classes = new Vector();
		File[] files = dir.listFiles(new FilenameFilter() {
			public boolean accept(File dir, String filename) {
				return filename.endsWith(".class");
			}
		});
		if (files!=null) {	// directories without .class files may exist
			for (int j = 0; j < files.length; j++) {
				String className = packageName + "." + files[j].getName();
				className = className.substring(0, className
						.lastIndexOf(".class"));
				classes.add(Class.forName(className));
			}
		}
		return classes;
	}
	/**
	 * Convert the package name into a relative directory path
	 * @param packageName name of the package as 'ch.sahits.civ'
	 * @return relativ directory to the package
	 */
	private String convertPackege(String packageName) {
		String sep = File.separator;
		return packageName.replace(".", sep);
	}
	/**
	 * Retrive all classes of the indicated package and all subpackages. The package is searched in
	 * all classpath directories that are directories
	 * 
	 * @param packageName
	 *            name of the package as 'ch.sahits.civ'
	 * @return Array of found classes
	 * @throws ClassNotFoundException
	 */
	public Class[] getAllRecursive(String packageName) throws ClassNotFoundException {
		String packageDir = convertPackege(packageName);
		Vector classes = new Vector();
		for (int i = 0; i < binDirs.length; i++) {
			packageDir = binDirs[i] + File.separator + packageDir;
			File dir = new File(packageDir);
			classes.addAll(extractClasses(packageName, dir));
			if (dir.isDirectory()) {
				File[] sub = dir.listFiles();
				for (int j = 0; j < sub.length; j++) {
					if (sub[j].isDirectory()) {
						Class[] rec = getAllRecursive(packageName + "."
								+ sub[j].getName());
						Vector temp = new Vector(rec.length);
						for (int k = 0; k < rec.length; k++) {
							temp.add(rec[k]);
						}
						classes.addAll(temp);
					}
				}
			}
		}
		Class[] result = new Class[classes.size()];
		classes.copyInto(result);
		return result;
	}
}

Vielleicht sollte an dieser Stelle noch bemerkt werden, dass ein solches Vorgehen wohl überlegt sein soll, denn nur mit diesen Informationen ist es nicht nicht möglich, die Methode auszuführen, den dazu wird noch ein Objekt benötigt, auf welchem die Methode ausgeführt werden kann und wenn man dieses hat, kann man sich den Umweg über den Classpath sparen.

Datenstrukturen in Java

Datenstrukturen und Java klingt im ersten Moment nach einem Widerspruch: Java hat Objekte und keine Strukturen. Bei näherer Betrachtung sieht man jedoch, dass die vermeintlichen Datenstrukturen zumindest in C++ als Klassen und somit als Objekte realisiert sind – alleine die Bezeichnung ist noch ein Ãœberbleibsel aus prozeduralen C-Zeiten.
Wir können also festhalten, dass eine Datenstruktur Attribute und Funktionen hat (um die Sprache möglichst neutral zu halten). Unterschiedliche Datenstrukturen haben unterschiedliche Attribute und Funktionen. Dies steht im Gegensatz zum objektorientierten Ansatz der Wiederverwendung von Objekten.
Java bietet von Haus aus bereits ein grosses Repertoire (JDK) wo man mit C++ die STL bemühen muss. So lässt sich in Java eine FIFO Queue bereits durch die Klassendefinition und dem Überschreiben von remove vollständig implementieren:

public class FIFOList extends LinkedList implements Queue{
    public Object remove() {
        return remove(0);
    }
}

Beispiel von: Simple Thoughts
Wenn ich jedoch den durch die Struktur beschriebenen Funktionsumfang anschaue muss ich feststellen, dass die Funktionalität zwar der einer FIFO Queue entspricht, aber bereits die Methodennamen leicht verwirrlich sind. Zudem gibt es zahlreiche Funktionen, die mit einer FiFo Queue nichts zu tun haben. Ein C++ Entwickler, der nur die Signaturen sieht kann nicht erkennen, worum es sich handelt. Zudem weiss ich mit einer solchen Umsetzung nicht wie die Queue funktioniert.
Aus diesem Grund habe ich die C++ Implementation genommen, sie für Java angepasst und mit einigen convenient Methoden ergänzt:

public class FiFoQueue {
	private FiFoNode first=null;
	private FiFoNode last=first;
	public FiFoQueue(){		
	}
	// Put a new elemnt in the queue
	public void enqueue(T element){
		FiFoNode temp = new FiFoNode();
		temp.value=element;
		temp.next=last;
		last=temp;
	}
	// Get the element from the queue that is in front
	public T dequeue(){
		FiFoNode temp = first;
		first=first.next;
		return temp.value;
	}
	// Check if the queue is empty
	public boolean isEmpty(){
		return first==last && first==null;
	}
	// Empty the queue
	public void empty(){
		first=last=null;
	}
	class FiFoNode{
		FiFoNode next;
		T value;
		FiFoNode(){
		}
	}
}