Config4J

Hallo liebe Leute es gibt mal wieder etwas neues von mir. :smiley:

Und zwar hab ich mich in letzter Zeit mit einer Bibliothek beschäftigt, die sich um das Speichern und Verwalten von Einstellungen und „Modulen“ bzw. Laufzeitkomponenten kümmert.
Die Idee dazu kam mir, da ich immer wieder mit Gedanken darüber machen musste wie ich Einstellungen verwalte und speichere. Mit diesen Gedanken im Hintergrund habe ich mit „Config4J“ begonnen.

Was beinhaltet die Bibliothek?
Im Kern enthält Config4J 2 Klassen (Configuration und Environment) zum Speichern von Einstellungen bzw Komponenten. Ich habe diese Aufteilung gewählt da diese jeweils anders gespeichert werden sollten und andere „Zwecke“ haben.
Um „beliebige“ Daten speichern zu können benötigt man für jeden Typ an Daten einen Parser der durch die Klasse „Setting“ repräsentiert wird, der auch gleichzeitig das verwalten der Schlüssel zuständig ist. Alle Daten werden per Schlüssel identifiziert und gespeichert.
Dadurch ist es nun sehr einfach Möglich die Daten (z.B. in eine Datei) zu speichern und wieder daraus zu laden.
Bei der Verwaltung der Komponenten ist der Gedanke eher an die Laufzeit. Dort können z.B. verschiedene Globale Klassen oder ähnliches auch unter einem Schlüssel gespeichert werden. Falls diese Objekte Serialisierbar sind kann man sie auch persistent Speichern.

Zusätzlich zu diesen beiden Wegen kann man das Speichern auch „aufspalten“ so das verschiedene Schlüssel bzw Schlüssel mit einem bestimmten Startwert an verschiedene Orte gespeichert werden und einfach wieder zusammengefügt werden.
Dazu gibt es noch 2 Annotationen für Attribute die es ermöglichen ein Attribut automatisch mit den entsprechenden Werten zu füllen und (falls ein neuer Wert für ein bestimmten Schlüssel gespeichert wurde) auf dem neuesten Stand zu halten. Dieses Verhalten ist allerdings auch ohne Annotation möglich.

Um sich keine Gedanken um das Speichern dieser beiden „Hauptklassen“ zu machen wurden zusätzlich 2 statische Klasen angelegt die es ermöglichen schnellzugriff auf eine der beiden Verwaltungsklassen zu erhalten.

So tl;dr und da eine Wall of Text auch ganz schön öde ist, kommt jetzt ein bisschen Code als Anschauung:
Anlegen einer neuen, leeren Configuration:
Configuration conf=new Configuration();
Erzeugen einer neuen „Einstellung“ (Setting) für boolean mit dem Schlüssel „foo.bah“:
Setting mySet=new BooleanSetting(„foo.bah“);

Um nun der Configuration einen Wert für eine Einstellung zu speichern reicht:
conf.put(mySet,true);
Mit conf.get(mySet); erhält man den gespeicherten Wert, der direkt in den entsprechenden Typ des Settings gesparsed wird.
Das gleiche funktioniert analog mit der Environment, nur das man dort auch direkt Strings als Schlüssel nehmen kann aber auch Settings wobei von diesen nur der String-teil genutzt wird.
Speichern kann man beide nun jeweils mit einem OutputStream bzw mit einem InputStream laden.
Für den Schnellzugriff sind die Klassen C (für Configuration) bzw. E (für Environment) zuständig die über statische Setter und Getter angesprochen werden können.
Um ein Objekt das eine der beiden neuen Annotationen besitzt konfigurieren zu können besitzen sowohl Configuration als auch Environment die Methode configure(Object); welche die Attribute mit den Annotationen entsprechend füllen. Über die Annotation kann man auch die automatische Aktualisierung aktivieren die per Standard deaktiviert ist. Eine automatische Aktualisierung kann man auch über add(String key, Object inst, String fieldName); in Configuration und Environment erreichen.

Hinweise: Über die Klasse LogSystem kann man diverse Einstellungen machen die sich auf das Logging innerhalb von Config4J beziehen, da ich keine Abhängigkeiten an andere Bibliotheken wie etwa Log4J haben wollte.
Vermutlich ist alles total konfus und unverständlich aber ich denke das wichtigste hab ich angesprochen. Alle Klassen und Methoden sollten dokumentiert sein und somit selbsterklärend. Ich lade gleichzeitig zur eigentlichen Bibliothek den Source-Code sowie die Dokumentation hoch.

Und nun viel Spaß beim Zerpflücken :smiley:

*** Edit ***

Die Api kann man sich übrigens hier anschauen: API

Ich browse gerne Code aber am liebsten auf einem online Repository :slight_smile: Wenn du’s eh im Source öffentlich stellst, wäre es ganz angenehm das auf ein Github-Repo zu pushen.

Pff da muss erstmal dann schauen wie ich das mache ^^ Aber wenn dir das lieber ist werd ich das in Angriff nehmen

Edit:
So denke habs geschafft (find jetzt SVN noch besser^^). Aber hier der Link: Config4J

Also wenn ich den Code richtig verstehe hat deine Library 3 Kernfeatures:

  1. Configs können typsicher ausgelesen werden
  2. Configs können auf mehrere Files verteilt werden und zentral ausgelesen werden.
  3. Man kann eine Observer-Funktionalität aktivieren um von Änderungen informiert zu werden.

Für diese Funktionalität ist das eine Menge Code. Der Code selbst ist aufgeräumt. Zuviele Kommentare in denen keine wichtige Information steckt ansonsten kann ich mich des Gefühls nicht erwehren, dass es over-engineered ist durch die vielen Interfaces und Klassen die dann kaum Funktionalität enthalten. Allerdings ist das nur ein kleines Manko wenn’s eh funktioniert.

Ich frag mich nur wo ich diese Lib einsetze anstatt 0815-Properties-Files.

Also im primären Sinne gings mir um die typsicherheit. Bei nem normalen Propertie hat man ja letztendlich nur <String,String> und muss sich kümmern alles in den richtigen Typ zu bringen.
Sekundär hab ich mir gendacht mit der Environment Klasse “Komplexere” globale dinge einfacher zugänglich zu machen. Ich hab z.B. in einem anderen Projekt diverse Controller die ich so gut zentral ablegen kann. Außerdem kann man damit “leicht” Dinge speichern die man schlecht in und von String wandeln kann aber serialisierbar sind.
Eine Ternräre Funktionalität (wer weiß wie sinnvoll die letztendlich ist) sind die Annotationen mit denen man (etwas an JavaFX angelehnt) attribute automatisch befüllen lassen kann bzw bei Änderungen der entsprechenden Schlüssel diese aktualisiert werden.

Hallo,

das was mir auffällt ist vor allem, dass ich keine Tests finde?

Gruß
Karl-Heinz

Also bisher ist das meiste manuell getestet aber ich hab inzwischen für die Configuration UnitTests gemacht und werd auch für den Rest noch welche machen