Enumerationen unter Java mit Eigenschaften ausstatten

Im Gegensatz zu vielen anderen Programmiersprachen sind Enumerationen unter Java ein wenig anders gestrickt. Wird eine Enumerationen dort kompiliert entsteht als Ergebnis eine Klasse. Dieser Umstand kann für interessante Dinge genutzt werden. Während in C# der Enum:

public enum Unit {
    PASCAL,
    PSI
}

eine reine Enumeration, mit zwei Werten, darstellt, kann die Enumeration unter Java mit zusätzlicher Funktionalität ausgestattet werden:

public enum Unit {

    PASCAL("Pascal", 1),
    PSI("Pound-force per square inch", 6.895);

    Unit(String name, double conversionFactor) {
        this.name = name;
        this.conversionFactor = conversionFactor;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getConversionFactor() {
        return conversionFactor;
    }

    public void setConversionFactor(double conversionFactor) {
        this.conversionFactor = conversionFactor;
    }

    private String name;
    private double conversionFactor;
}

In diesem Fall erhält die Enumeration zwei zusätzliche Eigenschaften, einen Namen und einen Faktor zur Umrechnung in Pascal. Bei der Definition der einzelnen Werte der Enumeration werden diese zusätzlichen Eigenschaften über den Konstruktor übergeben. In der Nutzung sieht das Ganze dann wie folgt aus:

Unit unit = Unit.PSI;

System.out.println(unit.getName());
System.out.println("Conversion factor to Pascal: " + unit.getConversionFactor());

Mit dieser Herangehensweise lassen sich Enumerationen unter Java einfach mit dazugehörigen Metadaten bzw. zusätzlichen Informationen anreichern.

Bibliothek zur Nutzung der MediaWiki-API unter .NET

Für ein kleines Projekt war ich auf der Suche nach einer halbwegs aktuellen Bibliothek zur Nutzung der MediaWiki-API. Wenn man sich auf der entsprechenden Seite in der MediaWiki-Dokumentation umschaut, wird man feststellen das einem nicht all zu viele Bibliotheken zur Verfügung stehen.

Die Auswahl an .NET Bibliotheken fällt eher mager aus

Genutzt habe ich letztendlich die Bibliothek Wiki Client Library, da diese halbwegs aktuell ist und mit meinen MediaWiki-Installationen problemlos zusammenarbeitet. Ein minimales Beispiel zur Bearbeitung einer Wiki-Seite sieht mit der Bibliothek wie folgt aus:

// Init
var client = new WikiClient
{
    ClientUserAgent = "WikiBot"
};

var site = new WikiSite(client, https://wiki.example.com/api.php);

// Login
await site.Initialization;
try
{
    await site.LoginAsync("username", "password");
}
catch (WikiClientException ex)
{
    Console.WriteLine(ex.Message);
}

// Edit site
var page = new WikiPage(site, buildingName);

// Load page
await page.RefreshAsync(PageQueryOptions.FetchContent);

// Update page
page.Content = "new content";
await page.UpdateContentAsync("New page created.", minor: false, bot: true);

// Logout
await site.LogoutAsync();

Über die Nutzung von Generatoren ist es möglich größere Bereiche wie z.B. Kategorien oder Suchergebnisse zu iterieren:

// Iterate all pages
var generator = new AllPagesGenerator(site)
{
    StartTitle = "A",
    NamespaceId = BuiltInNamespaces.Main,
    PaginationSize = 50
};

using (var enumerator = generator.EnumPagesAsync().GetEnumerator())
{
    int index = 0;

    while (await enumerator.MoveNext(CancellationToken.None))
    {
        // Debug output
        var page = enumerator.Current;
        Console.WriteLine("{0}: {1}", index, page);
        index++;

        // Load page
        await page.RefreshAsync(PageQueryOptions.FetchContent);

        // Update page
        page.Content = "new content";
        await page.UpdateContentAsync("Update page.", minor: true, bot: true);
    }
}

Der Quelltext der Wiki Client Library ist auf GitHub zu finden. Lizenziert ist er unter der Apache Licence 2 und damit freie Software.

Mono-Probleme auf dem Raspberry Pi

Auf einem meiner Raspberry Pi-Rechner läuft eine in Mono geschriebene Server-Applikation. Damit die Server-Applikation funktionierte benötigte sie natürlich die Mono Runtime. Diese kann unter Raspbian einfach mittels des Kommandos:

apt-get install mono-runtime

installiert werden. Als ich die Serverapplikation nach der Installation von Mono ausführen wollte erhielt ich allerdings folgende Fehlermeldung:

Missing method .ctor in assembly Melinda.dll, type System.Runtime.CompilerServices.ExtensionAttribute
Can't find custom attr constructor image: Melinda.dll mtoken ...

Dieses Problem ließ sich durch die Installation der Bibliothek libmono-system-core4.0-cil beheben:

apt-get install libmono-system-core4.0-cil

Im Anschluss erhielt ich bei einem erneuten Startversuch eine weitere Fehlermeldung:

Grapevine.Exceptions.Server.UnableToStartHostException occurred
An error occured when trying to start the Grapevine.Server.RestServer

In diesem Fall kam die Fehlermeldung vom REST-API Framework Grapevine. Allerdings war der Fehler nicht wirklich in der Bibliothek zu finden. Stück für Stück kamen weitere Fehlermeldungen wie diese:

System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.

zustande. Nach einiger Recherche war klar: auch in diesem Fall fehlten weitere Abhängigkeiten aus dem Mono-Framework. In diesem Fall half die Holzhammermethode; die Installation des kompletten Mono-Frameworks. Dazu wurde das Paket mono-complete mittels:

apt-get install mono-complete

installiert. Dieses nimmt ein paar mehr Megabyte als das Runtime-Paket in Anspruch, allerdings sind damit alle möglichen Abhängigkeiten installiert. Somit kann man sich auf die eigentliche Entwicklung und Ausführung der eigenen Applikationen konzentrieren, anstatt einer kuriosen Fehlermeldung nach der anderen hinter her zu jagen.

REST-Server mit Grapevine aufsetzen

In den letzten Tagen habe ich für ein Projekt einen REST-Server geschrieben. Der Server läuft unter .NET bzw. Mono – also war ich auf der Suche nach einer passenden Bibliothek bzw. einem Framework, welches mich bei dem Aufsetzen eines solchen Servers unterstützt. Nach einem Blick auf Nancy und einigen anderen Frameworks bin ich schlussendlich bei Grapevine gelandet.

sukona.github.io

sukona.github.io

Dabei handelt es sich um eine Bibliothek, welche neben einem REST-Client auch einen REST-Server bereitstellt. Das Hauptaugenmerk der Entwicklung wird dabei auf den REST-Server gelegt. Mit Hilfe des Frameworks lässt sich ein REST-Server mittels weniger Zeilen Quellcode aufsetzen:

ServerSettings settings = new ServerSettings();
settings.Host = "localhost";
settings.Port = "1111";

RestServer server = new RestServer(settings);
server.Start();

In diesem Beispiel werden die Einstellungen für den Server angelegt und anschließend dem Server übergeben. Danach wird der Server mit der Methode Start hochgefahren. Damit verfügt man zwar über einen REST-Server, dieser verfügt allerdings über keinerlei Methoden was die praktische Verwendung eher erschwert. Ressourcen für den Server werden mittels des Attributes RestResource markiert:

[RestResource(BasePath = "/time/")]
public class TimeModule
{
    [RestRoute(PathInfo = "date")]
    public IHttpContext GetDate(IHttpContext context)
    {
        context.Response.SendResponse(Grapevine.Util.HttpStatusCode.Accepted, getDate());
        return context;
    }
}

Über das Attribut RestRoute wird eine Methode für Grapevine gekennzeichnet – das Pathinfo definiert dabei den Pfad über welchen diese aufgerufen werden kann. Durch den über das Attribut RestResource festgelegten BasePath lautet die vollständige URL für die Ressource:

http://localhost:1111/time/date

Wird diese Methode per GET aufgerufen, so wird das aktuelle Datum zurückgegeben. Damit ist ein minimaler REST-Server mit einer Ressource implementiert. Grapevine selbst ist unter der Apache Lizenz lizenziert und damit freie Software. Der Quelltext der Bibliothek befindet sich auf GitHub.

WriteMonkey

Vor einiger Zeit stellte ich die Software FocusWriter (als Alternative zum iaWriter) für das ablenkungsfreie Schreiben vor. Daneben gibt es weitere Alternativen – einer dieser Alternativen ist WriteMonkey. Im Gegensatz zum FocusWriter wirkt WriteMonkey aufgeräumter, was der Schreiberfahrung zu gute kommt. Außerdem unterstützt WriteMonkey Markdown und ermöglicht so das Schreiben von strukturierten Texten.

WriteMonkey im Einsatz

WriteMonkey im Einsatz

Im Gegensatz zum FocusWriter steht der WriteMonkey leider nicht unter einer freien Softwarelizenz; sondern wird als Freeware vertrieben. Zu finden ist WriteMonkey auf der offiziellen Seite unter writemonkey.com.