Herzlich willkommen auf dem Blog der exensio GmbH

exensio ist ein unabhängiges Software-Unternehmen von erfahrenen IT Beratern und Architekten. Zu unseren Kunden zählen namhafte deutsche Großunternehmen.

exensio verbessert das Kommunikations- und Informationsmanagement von Unternehmen. Auf Basis sinnvoller und zweckmäßiger Technologien erarbeiten wir flexible und übergreifende Lösungen für webbasierte Informationssysteme. Abhängig von den Kundenanforderungen realisieren wir Web Applikationen sowie Lösungen auf Basis von Web Content Management- und Portalsystemen. Integrativ, wirtschaftlich und anwenderfreundlich!

Hier gelangen Sie zur exensio GmbH.

Dienstag, 15. April 2014

JIRA Filter Browser Plugin

Bei exensio setzen wir für das Projektmanagement und Bugtracking JIRA ein. Auf der Startseite von JIRA gibt es einen Aktivity Steam, in dem alle Änderungen, die an Tickets vorgenommen werden angezeigt werden

Leider gibt es keine Möglichkeit bestimmte Änderungen nicht im Activity Stream anzuzeigen. Trägt zum Beispiel jemand bei einem Ticket die benötigte Arbeitszeit ein, wird das im Stream dargestellt, obwohl diese Information (in unserem Fall) für andere Mitarbeiter komplett uninteressant ist.


Dies hat zur Folge, dass sich im Activity Stream jede Menge Einträge finden und oftmals die interessanten bzw. wichtigen Sachen übersehen werden.  Für diesen Fall habe ich eine kleine Browsererweiterung geschrieben, die solche Einträge aus dem Activity Stream entfernt. Bisher werden nur Work Log Einträge aus dem Stream entfernt. Die Erweiterung ist frei auf Github verfügbar. Mit installiertem Plugin sieht das ganze dann so aus:


Technisch wird hierfür Javascript in die Seite eingebunden, das per Regular-Expression nach den ungewollten Einträgen sucht und diese anschließend entfernt. Sind danach weniger als 10 Einträge übrig und ältere zum Nachladen verfügbar, wird die Liste mit älteren Einträgen wieder aufgefüllt und wieder von vorne begonnen.

Download: https://github.com/exensio/jira-filter-plugin

Montag, 7. April 2014

Erster Java Saxony Day in Dresden

Nach der BED-Con ging es am darauffolgenden Tag gleich weiter zum Java Saxony Day in Dresden. Die Veranstaltung fand zum ersten Mal statt und wurde von der örtlichen Java User Gruppe organisiert. Mit 4 parallelen Tracks und einigen Ausstellern im Forum wurde viel geboten.

Mein Vortrag "Grails - schneller zum Ziel - für Enterprise Applikationen" war mit ca. 40-50 Personen erfreulich gut besucht. Auch wenn der Hype um Grails etwas zurückgegangen ist , zeigten mir die anschließenden Fragen, dass dieses Thema weiterhin von Interesse für die Java-Welt ist.

Von den wenigen Sessions, die ich selbst hören durfte, gefielen mir besonders "Java 8 Streams - How to Kick Ass with Lambdas" sowie "RESTful Services mit Dropwizard".

Die Veranstaltung wurde perfekt organisiert und die Resonanz von den Teilnehmern, mit denen ich sprechen konnte, fiel durchweg positiv aus.
Insofern wäre es schön, wenn der Java Saxony Day auch im nächsten Jahr stattfindet.

Sonntag, 6. April 2014

Berlin Expert Days 2014

Dieses Jahr besuchte ich das erste Mal die BED-Con und durfte gleich zusammen mit Florian Hopf einen Vortrag zum Thema "Search Driven Applications" halten.

Zu unserem Vortrag konnten wir über 100 Teilnehmer begrüßen. Im überfüllten Raum mussten einige Zuhörer stehen bzw. sich auf den Boden setzen. Der Vortrag verlief aus meiner Sicht sehr gut und es gab durchweg positives Feedback von den Teilnehmern. Selbst nach der Session durften wir noch viele Fragen rund um das Thema "Suche" beantworten, so dass wir den Beginn der nachfolgenden Sessions verpassten.



Nachmittags besuchte ich einige interessante Sessions selbst und war bei der Panel-Diskussion dabei.
Leider konnte ich nur am ersten Tag der BED-Con beiwohnen, da es am nächsten Tag schon weiterging Richtung Dresden zum Java Saxony Day.
Ich habe die BED-Con als Konferenz wahrgenommen, die sich auf das wesentliche einer Konferenz konzentriert: Super Vorträge mit einer guten Organisation.

Freitag, 28. März 2014

Bericht DevCamp Karlsruhe

Am Wochenende vom 22. bis zum 23. März fand das DevCamp Karlsruhe im Technologiepark Karlsruhe statt [1]. Hier nahm man mit anderen Entwicklern an verschiedensten Vorträgen teil, und konnte über jedes Thema, das einem am Herzen liegt, sprechen oder eine Diskussionsrunde halten. Die meisten Entwickler kamen aus dem Javascript Umfeld. Es fanden sich aber auch Java Programmierer sowie Vertreter anderer Sprachen. Alle Teilnehmer konnten Themen für Vorträge vorschlagen.

Eines der Highlights für mich, der Vortrag über Devoxx4Kids, fand gleich am Anfang statt. Als Dev-Vater interessiert mich, wie man Kindern programmieren beibringen kann. Das Motto von Devoxx4Kids »Your Kid Plays Games - Mine makes games« gefällt mir auf jeden Fall. Es fing mit Organisatorischem an, also was man beachten sollte, wenn man mit Kindern eine Veranstaltung organisiert. Es ging weiter mit verschiedenen Workshops, die mit Kindern durchführbar sind. Bereits kleinen Kindern kann man das Denken über Programmieren mit DrTechniko [2] näherbringen. Ältere Kinder editieren komplexe Spiele mit Alice [3] oder Minecraft [4] und lernen Robotik mit Lego Mindstorm oder Nao. Zum Schluss sahen wir eine Demo, wie man mit Kindern einen Rapsberry Pi programmiert. Wer mehr wissen will, kann die Homepage [5] von Devoxx4Kids besuchen oder im September beim ersten Devoxx4Kids Deutschland Treffen in Karlsruhe [6] teilnehmen. Dieser Vortrag wird noch auf der Java User Group in Karlsruhe [7] wiederholt und die Folien befinden sich hier [8].

Auf dem DevCamp gab es einige Vorträge aus dem ElasticSearch Umfeld, die Alexander Reelsen [9] hielt. Im Vortrag mit dem Titel »Einführung: Volltextsuche« ging es um Lucene und wie Dokumente indiziert werden. Wer mehr darüber erfahren will, kann es auch gleich auf unserem Blog [10] tun. Bei »Elasticsearch & Logstash« lernte ich, wie man mit Logstash [11] Informationen aus Logdateien extrahiert, sie dann in ElasticSearch speichert und mit Hilfe von Kibana [12] grafisch analysiert. In dem Vortrag wurden live Daten von Meetup angezeigt. Die Folien können hier [13] runtergeladen werden. Im letzten Vortrag ging es um »Elasticsearch, Java & Performance«, in welchem man einen Überblick darüber bekam, wie in ElasticSearch auf Performanz geachtet wird. Die Garbage Collections Settings wurden erklärt, sowie die Java Libraries, die ElasticSearch im Hinblick auf Performanz verwendet.

»Arbeiten von Zuhause/remote« war eine Diskussionsrunde, in welcher Leute, die von daheim aus arbeiten, über ihre Erfahrungen berichteten und erzählten, was für Vorteile und welche Herausforderungen es gibt. Gut zu wissen, dass man den Arbeitsplatz auf jeden Fall vom Wohnraum trennt, damit man nach der Arbeit abschalten kann. Es wurde viel über Tools gesprochen, die remote arbeiten einfacher machen, zum Beispiel um mit Mitarbeitern direkt zu kommunizieren oder Neuigkeiten auszutauschen.

Im »Mean Backend« Talk erstellte Tim Suchanek [14] live eine einfache CRUD (create, read, update, delete) Anwendung mit Hilfe des MEAN [15] Stack. MEAN steht für MongoDB [16], Express [17] (ein Webframework für Node.js), AngularJS [18] und Node [19]. Als Ausgangspunkt dient Angular Seed [20], welches ein Skelett für eine AngularJS Anwendung bereitstellt und so für einen leichten Einstieg sorgt. Das Erstellen der Anwendung ging einfach von der Hand. Beim zweiten Vortrag, in welchem das Frontend mit Angular entwickelt worden ist, konnte ich leider nicht mehr teilnehmen. Die Anwendung ist auf Github [21] verfügbar.

Das DevCamp endete für mich mit einem weiteren Highlight: »Überwache deine Web-App mit Graphite«. Graphite [22] ist sehr flexibel, und es ist einfach, Daten an Graphite zu senden. Es gibt vorgefertigte Pakete, die Daten sammeln, wie z.B. CPU oder Memory Auslastung, und an Graphite senden.  Die Ansicht von den Daten in der Graphite Webapp ist spartanisch, es gibt aber auch da alternative Dashboards. Nachteilig erwähnt wurde, dass es schwer zu installieren ist.

Als Fazit kann ich sagen, dass es mir gut gefiel. Ich lernte viele interessante Sachen und nette Leute kennen und werde beim nächsten Mal wieder teilnehmen.

Links

[1] http://www.nerd-zone.com/devcamp
[2] http://drtechniko.com
[3] http://www.alice.org
[4] https://minecraft.net
[5] http://www.devoxx4kids.org/deutschland
[6] http://www.devoxx4kids.org/deutschland/veranstaltungen
[7] http://jug-karlsruhe.mixxt.de/networks/events/show_event.92251
[8] http://www.devoxx4kids.org/deutschland/wp-content/uploads/sites/5/2014/03/d4k_praesentation.pdf
[9] https://twitter.com/spinscale
[10]http://blog.exensio.de/2013/09/zweitagiges-elasticsearch-training-in_24.html
[11]http://logstash.net
[12]http://www.elasticsearch.org/overview/kibana
[13]https://speakerdeck.com/elasticsearch/using-elasticsearch-logstash-and-kibana-to-create-realtime-dashboards
[14] https://twitter.com/TimSuchanek
[15] http://www.mean.io
[16] https://www.mongodb.org/
[17] http://expressjs.com/
[18] http://angularjs.org
[19] http://nodejs.org
[20] https://github.com/angular/angular-seed
[21] https://github.com/crowddining/einkaufszettel
[22] http://graphite.readthedocs.org

Freitag, 21. März 2014

ClaretPortal wird mobil (Teil 4) - Fokus: Volltextsuche mit jQuery Mobile

In den ersten drei Teilen dieser Blog-Serie [1] [2] [3] habe ich alle Basis-Funktionalitäten gezeigt, die man heutzutage von einer mobilen Web-Applikation erwartet. Hervorzuheben sind dabei das klare und übersichtliche UI-Design über Standard-Komponenten von jQuery Mobile sowie das Scrollen von Listen (Endless / Infinite Scroll) im Gegensatz zu einer Blätterung.
Bei Scrollen von Listen wurde dabei schon die Einbindung eines Backend-Servers betrachtet, denn logischerweise müssen beim Scrollen Daten nachgeladen werden. Dieser Beitrag soll zeigen, wie auf einfache Art und Weise die Standard-Komponente ListView mit Suchfeld dazu benutzt werden kann, um beliebige Daten serverseitig zu durchsuchen, z.B. eine Volltextsuche mit Elasticsearch [4].

jQuery Mobile ListView mit Filterable Widget

In einer jQuery Mobile ListView lässt sich einfach über das Attribut data-filter="true" (bitte die Hinweise im jQuery Mobile 1.4 Upgrade Guide [5] beachten) ein Suchfeld über der Liste anzeigen. Standardmäßig durchsucht dieses Suchfeld automatisch alle Elemente, die in der Liste dargestellt werden. Das ist für eine Filterfunktion bestens geeignet, stößt aber an seine Grenzen sobald Daten durchsucht werden sollen, die noch nicht am Client verfügbar sind. Für diesen Zweck bietet das Widget allerdings einen Event-Mechanismus, mit welchem die vom Benutzer eingetippten Suchanfragen abgefangen und an einen Server weitergeleitet werden können.

Filterable Widget und das filterablebeforefilter-Event

Das filterablebeforefilter-Event ist immer dann geeignet, wenn das ListView-Suchfeld eine andere Datenmenge dursuchen soll als aktuell tatsächlich in der ListView dargestellt wird. Das kann zum einen dafür benutzt werden, um bestimmte Tags zu durchsuchen, die beispielsweise in versteckten DIV-Containern vorgehalten werden. Es lässt sich zum anderen aber auch benutzen, um Suchanfragen an eine Volltextsuche wie Elasticsearch zu schicken und das Ergebnis im Anschluss dann in der ListView anzuzeigen. Das Look & Feel bleibt für den Benutzer dabei unverändert, er "weiß nicht", dass die Daten von einem entfernten Server kommen.

Das folgende Bild zeigt das vom Server über Elasticsearch kommende Suchergebnis im gewohnten jQuery Mobile Design:

Die technische Realisierung

Die Funktionsweise besteht aus zwei grundlegenden Komponenten.

Die ListView mit Filterable Widget

<div id="studyListContainer" data-role="content" data-theme="a">
 <g:link action="list" class="search-query-link" style="display:none">Search query</g:link>

 <ul class="study-list" data-role="listview" data-filter="true" data-filter-placeholder="Search all studies">
  <g:render template="studyList" model="[pageScope.variables]"  />
 </ul>
</div>

Der Javascript-Aufruf

$("#list").find(".study-list").on("filterablebeforefilter", function (e, data) {
 var $ul = $(this);
 var $input = $(data.input); // Get user's search input
 var value = $input.val();
 var html = "";
 $ul.html(""); // Clear list
 if (value && value.length > 2) {
  $.mobile.loading('show'); // Show default loading icon
  var theUrl = $('.search-query-link').attr("href");
  $.ajax({
   url: theUrl,
   dataType: "html",
   crossDomain: true,
   data: {
    query: $input.val() // Query param for server
   }
  })
  .then(function (data) {
   $.mobile.loading('hide'); // Upon receiving data, hide loading icon
   $ul.html($(data).find(".study-list li")); // Insert result into list
   $ul.listview("refresh"); // Apply jQuery Mobile Look & Feel
  });
 }
});
Das Event "filterablebeforefilter" wird bei jeder Änderung des Suchfelds gefeuert und triggert mit obigem Javascript-Aufruf einen Server-Request - in unserem Fall an einen Grails-Controller, der wiederum über einen Service Elasticsearch abfragt. Der Grails-Controller rendert die herkömmliche View, die die ListView mit den zur Suche passenden Ergebnisse erhält. Die List-Items dieser ListView werden im vorletzten Aufruf einfach in die bestehende Liste eingefügt.

Fazit

Dieser Beitrag zeigt, wie einfach sich auf mobilen Endgeräten auch komplexe Aktionen wie eine Volltextsuche darstellen lassen. Dabei muss der Client keine Logik verwalten - er sendet lediglich den Suchbegriff und der Rest wird vom Backend übernommen. Durch entsprechende Ladesymbole ist dieses Vorgehen für den Benutzer transparent.
Das in Teil 3 vorgestellte Endless Scrolling lässt sich auch hier ohne weiteres Zutun in Kombination verwenden. Die perfekte Such-App!

Links

[1] ClaretPortal wird mobil (Teil 1) - Fokus: jQuery Mobile ListViews
[2] ClaretPortal wird mobil (Teil 2) - Fokus: jQuery Mobile Grid & Collapsible Set
[3] ClaretPortal wird mobil (Teil 3) - Fokus: Endless/Infinite Scrolling mit jQuery Mobile
[3] exensio setzt auf Elasticsearch
[4] jQuery Mobile 1.4 Upgrade Guide - Filter

Mittwoch, 19. März 2014

Visualisierung von geometrischen Formen mit Hilfe von SVG und HTML5

In diesem Blogpost möchte ich anhand eines Beispiels die Verwendung von SVG mit Hilfe der Bibliothek Snap.svg [1] veranschaulichen. Als Beispiel soll die Erstellung eines Straßenzuges dienen, bei der die einzelnen Teilabschnitte der Straße eines gesamten Straßenzuges als Zeichnung erstellt werden soll. Die Zeichnung soll auch bei starker Vergrößerung keine Qualitätsverluste aufweisen.

Abbildung 1: Beispiel für einen Straßenzug



Zunächst stellt sich die Frage warum bei diesem Beispiel nicht das mit HTML 5 ebenfalls eingeführte Canvas verwendet wird. Um dies zu beantworten wird zunächst eine kleine Gegenüberstellung von Canvas zu SVG gegeben.

Canvas vs. SVG
Canvas wurde im Zuge von HTML5 eingeführt und ist wie der Name schon vermuten lässt eine „Leinwand“ mit der man über Javascript dynamische Bitmap-Grafiken zeichnen kann. Da Canvas pixelbasiert ist, sind die entstehenden Grafiken nicht auflösungsunabhängig. Beim skalieren der Grafik werden Unschärfen an den Rändern sichtbar. Die Zeichnungen lassen sich einfach als PNG, BMP oder JPEG abspeichern. Jedoch können einzelne Objekte der gesamten Zeichnung nicht nachträglich bearbeiten werden. So funktioniert die Canvasoberfläche im Prinzip wie das bekannte Zeichenprogramm Paint von Microsoft.
SVG ist Vektorgrafikbasiert und somit auflösungsunabhängig. Aufgrund der Vektorgrafik können auch Fließkommazahlen dargestellt werden. Hingegen können bei Canvas nur ganzzahlige Pixelwerte verwendet werden. Auch bei starkem Hinein-zoomen in die Zeichnungen „verschwimmen“ keine Linien und Kanten. Einzelne Objekte können nachträglich noch bearbeitet werden. Um SVG einfach zu verwenden wird die Bibliothek Snap.svg verwendet. Diese bietet die Möglichkeit mit SVGs ähnlich zu manipulieren wie für das DOM mit JQuery möglich ist. Snap.svg wird von Adobe unterstützt und ist eine Open Source Library. Die Bibliothek benötigt mindestens IE9, Firefox, Chrome oder Opera.

Beispiel für Verwendung von SVG
Nun zum oben schon angesprochenen Beispiel. Der Einfachheit halber wird der Straßenzug aus einzelnen Teilabschnitten zusammengesetzt, wobei jeder Teilabschnitt durch ein Viereck repräsentiert wird. Auf das Erstellen von Kurven wird in diesem Blog Post nicht eingegangen. Die Abmessungen der einzelnen Teilstrecken könnten z.B. aus einer Datenbank geladen werden, um das Beispiel einfach zu halten wird an dieser Stelle darauf verzichtet. Nachfolgend ist in Abb. 2 die Eingabemaske für das Zeichentool zu sehen. In diesem Fall besteht das der gesamte Straßenzug aus 4 Teilstrecken. Eine Erweiterung ist durch den Button „Teilstrecke hinzufügen“ möglich.

Abbildung 2: Eingabemaske


Eine weitere Anforderung ist das dynamische Erweitern der Zeichenfläche, dies wird benötigt falls die aktuelle Zeichenfläche zu klein für den gesamten Straßenzug sein sollte. In der Zeichnung werden desweiteren die Abmessungen der Teilabschnitte benötigt. In diesem Beispiel wird zudem noch die jeweilige Fläche der Teilabschnitte berechnet. Siehe Abbildung 1: Beispiel für einen Straßenzug.
Nach einbinden der Bibliothek Snap.svg kann eine Zeichenfläche einfach erstellt werden.


Abbildung 3:Erstellen von Zeichenflächen


Die Zeichenfläche kann nun über Javascript manipuliert werden. Um einen Teilabschnitt zu erstellen wird aus der Bibliothek die Funktion path(„String“) benötigt. Hier werden die Eckpunkte angegeben und mit Linien zu einem vollständigen Pfad erstellt. Dabei bedeuten „M“ move, „L“ line und „Z“ close Path. Attribute wie Linienfarbe, Linienstärke und Füllung können festgelegt werden.

Abbildung 4: Erstellen von Teilabschnitten


Hierdurch können einzelnen Teilabschnitte nacheinander erstellt werden. Die Bemaßung kann mit der Funktion text(x, y, String) einfach erstellt werden. Wobei (x,y) die Position des Textes angibt. Die Ausrichtung kann durch die Funktion rotate(a, x, y) festgelegt werden.
Eine weitere Funktion, die das kleine Beispiel besitzen soll, ist das dynamische Erweitern der Zeichenfläche. Hierzu muss lediglich das Attribut „width“ der Zeichenfläche verändert werden. Diese kann über jQuery einfach angesprochen werden. Die Objekte die bereits erstellt wurden, werden hierdurch nicht beeinflusst.

Fazit
Durch das Beispiel des Straßenzuges konnte gezeigt werden, dass unter Verwendung der Open Source Bibliothek Snap.svg vektorbasierte Zeichnungen einfach erstellt werden können. Hier wurden nur 3 Funktionen der sehr umfangreichen Bibliothek verwendet. Die Objekte lassen sich einfach über Javascript erstellen. Die Zeichnungen sind auflösungsunabhängig und somit auf jedem Bildschirm unter Verwendung moderner Browser „scharf“ darstellbar und skalierbar. Die Verwendung von SVG ermöglicht es ebenfalls nachträglich einzelne Objekte zu manipulieren oder auch Informationen aus der Zeichnung zu extrahieren, was einen deutlichen Vorteil gegenüber pixelbasierten Lösungen bietet.

Links
[1] http://snapsvg.io/