# Eigene API erstellen?



## Kababär (11. Jul 2016)

Hi,

kann man sich in Java eine eigene API ähnlich wie die API von Apache selbst programmieren?
Wie funktioniert so was?

Edit: Also klar, eigene Libs erstellen etc. Aber mal angenommen ich hätte keine Apache POI zum Auslesen von Word und Excel Dateien oder will was neues auslesen. Wie gehe ich da vor?


----------



## Thallius (11. Jul 2016)

Du erzeugst einfach eine .jar aus deinem Code und schon kannst du diese wie eine lib in jeden anderen Code einbinden.


----------



## Kababär (11. Jul 2016)

Ja gut das weiß ich.. aber wie fange ich an ein Rad zu erfinden?
Beispielsweise wie gehe ich voran, wenn ich ohne eine API oder sonst was eine .doc-Datei einlesen will?
Wie erschaffe ich mir mein eigenes Werkzeug?


----------



## thecain (11. Jul 2016)

Lernen wie man doc Dateien parst...

Sowas kommt immer auf die konkrete Problemstellung an.


----------



## Baldur (12. Jul 2016)

Hm, hast du tatsächlich vor, .doc Dateien zu lesen oder war das nur ein Beispiel? .doc ist ziemlich komplex (evtl nichtmal öffentlich dokumentiert?)
Ggf solltest du erst mal schaun welche alternativen Formate es gibt, und ob es dazu schon öffentliche Dokumentation gibt (für formatierten Text wäre z.B. RTF eine Alternative)
Wenn ein Format nicht dokumentiert ist, muss man das reverse engineeren. Das heißt, du fängst an, dir das Ding im Hexeditor anzuschaun, vergleichst verschiedene Dateien und versuchst herauszufinden, wie der Header der Datei aufgebaut ist und hangelst dich dann Schritt für Schritt voran, bis du das Format verstanden hast. Dann schaust du dir weitere Dateien in dem Format an und findest haufenweise neuer Details, die du berücksichtigen musst 

Falls ich dein Anliegen vollkommen falsch verstanden habe, kannst du ja noch einmal genauer beschreiben, was du vor hast.


----------



## Kababär (12. Jul 2016)

Das war nur ein Beispiel. Habe die Tage mal veruscht, .doc und .xdoc Dateien zu bearbeiten und fand, wie man das mittels Apache POI gestaltet, einfach nur furchtbar und grausam 
Dann kam die Idee (generell): wie macht man so was? Wie hat das Apache POI eigentlich gemacht?

Das heißt, ich suche im Internet nach dem technischen Aufbau einer solchen Datei, für die ich eine Lib schreiben will? Das stelle ich mir eigentlich sehr cool vor. So etwas ähnliches haben wir mit DICOM Dateien an der FH gemacht, aber diese sind dann doch eher schlicht aufgebaut im Vergleich zu Word-Dateien.
Also im Prinzip brauche ich eine Referenz so wie diese hier?
https://msdn.microsoft.com/de-de/library/office/gg615596(v=office.14).aspx
Oder generell eine DTD/XML?

Eignet sich zwangsläufig Java dafür? (wegen nicht vorhandener Unterscheidung zwischen signed/unsigned bits könnte es doch zu Problemen führen beim Interpretieren von Bytes?)

Reverse Engineering habe ich noch nie gemacht.. aber solche APIs zu erstellen gefällt mir sehr gut. Nur alleine wird das ein Jahrhundertprojekt, oder?

Edit: Also .doc-Dateien waren nur ein Beispiel. Als erstes würde ich mich mal an kleineren Projekten orientieren. Ich denke das Prinzip bleibt immer das Gleiche? Format und Aufbau einer Datei rausfinden, binär/hexadezimal einlesen und interpretieren? Vielleicht fange ich mit Audio-Dateien an und gehe dann weiter Richtung Textverarbeitung aber für OpenOffice. Bin nicht wirklich Microsoft-begeistert.


----------



## Thallius (12. Jul 2016)

Kababär hat gesagt.:


> So etwas ähnliches haben wir mit DICOM Dateien an der FH gemacht, aber diese sind dann doch eher schlicht aufgebaut im Vergleich zu Word-Dateien.



Dann habt ihr aber nur einen ganz kleinen Teil von DICOM analysiert. DICOM ist im ganzen extrem komplex. Da ist eine Word-Datei nicht komplizierter.

Gruß

Claus


----------



## Kababär (12. Jul 2016)

Thallius hat gesagt.:


> Dann habt ihr aber nur einen ganz kleinen Teil von DICOM analysiert. DICOM ist im ganzen extrem komplex. Da ist eine Word-Datei nicht komplizierter.
> 
> Gruß
> 
> Claus



Das kann sehr gut sein. Uns ging es zwar nur um die Bilder, aber die anderen "Tags" habe ich auch rausgelesen. Ich nehme aber mal an, dass der Prof uns nur unvollständige DICOM-Dateien gegeben hat.
Das ganze mit C# zu programmieren, war sehr angenehm


----------



## Thallius (12. Jul 2016)

Kababär hat gesagt.:


> Das kann sehr gut sein. Uns ging es zwar nur um die Bilder, aber die anderen "Tags" habe ich auch rausgelesen. Ich nehme aber mal an, dass der Prof uns nur unvollständige DICOM-Dateien gegeben hat.
> Das ganze mit C# zu programmieren, war sehr angenehm



Ich habe mir vor ein paar Jahren einen eigenen DICOM parser in Java geschrieben, der auch nur ca 20% der DICOM Features abdeckt und das war schon nicht ohne. Also Bilder wirklich mit read auf der Datei lesen und die Tags alle analysieren. Ohne Verwendung irgendeiner Library. Also quasi das was Du gerade machen möchtest.

Gruß

Claus


----------



## Baldur (12. Jul 2016)

Kababär hat gesagt.:


> Das war nur ein Beispiel. Habe die Tage mal veruscht, .doc und .xdoc Dateien zu bearbeiten und fand, wie man das mittels Apache POI gestaltet, einfach nur furchtbar und grausam
> Dann kam die Idee (generell): wie macht man so was? Wie hat das Apache POI eigentlich gemacht?


In dem Fall gibt es z.B. auch die Möglichkeit, sich einen Wrapper zu schreiben 
POI ist ja wahrscheinlich deshalb so komplex, weil es versucht möglichst viele Features abzudecken, die .doc bietet. Aber wenn du sagst "hey, eigentlich muss ich mir doch bloß aus einem .doc Textfragmente extrahieren oder ersetzen, Bilder, Tabellen interessieren mich nicht", kannst du dir eine eigene API bauen, die zwar hintenrum POI verwendet, aber die wesentliche Funktionalität, auf die es dir ankommt, vereinfacht.



Kababär hat gesagt.:


> Reverse Engineering habe ich noch nie gemacht.. aber solche APIs zu erstellen gefällt mir sehr gut. Nur alleine wird das ein Jahrhundertprojekt, oder?


Kommt letztendlich auf das Format drauf an. Die MS-Office Formate sind ja anfangs auch für andere Officeprogramme reverse engineered worden, weil es keine öffentliche Dokumentation gab. Aber das hat halt keiner alleine gemacht.
Wenn du sowas rein aus Interesse probieren willst, kannst du ja am Anfang mal versuchen, einfache Formate wie .bmp zu reverse engineeren. bmp ist halt sehr, sehr einfach, aber du kannst schonmal lernen wie du rausfinden kannst, wie der Header aufgebaut ist. Und notfalls kannst du auch noch spicken


----------



## Kababär (12. Jul 2016)

Thallius hat gesagt.:


> Ich habe mir vor ein paar Jahren einen eigenen DICOM parser in Java geschrieben, der auch nur ca 20% der DICOM Features abdeckt und das war schon nicht ohne. Also Bilder wirklich mit read auf der Datei lesen und die Tags alle analysieren. Ohne Verwendung irgendeiner Library. Also quasi das was Du gerade machen möchtest.
> 
> Gruß
> 
> Claus


Ja so was haben wir auch mit C# gemacht. Also bis zur Byte-Position 128 springen, checken ob die 4 nachfolgenden Bytes "DICM" sind, hexadezimalcodierte Tags auslesen, implizit/explizit (VR ja, nein?), etc.
Bis vorhin war mir irgendwie nicht so ganz klar, dass es für jede Datei wirklich so strikte Vorgaben bezüglich des Aufbaus bzw. eine öffentliche Dokumentation gibt.
Hätte ja sein können, dass man dafür Lizenzen braucht oder so, damit nicht jeder einfach APIs bauen kann.



> In dem Fall gibt es z.B. auch die Möglichkeit, sich einen Wrapper zu schreiben


Ok klingt einfach. Ich schreibe mir eine Klasse mit der Methode insertText(Params par...) und in dieser Methode verwende ich XWPF oder HWPF. 
Umgekehrt geht das auch so nehme ich mal. Ich verwende die Grundlagen von Apache um auf eine gewisse Seite zu kommen (bspw) und schreibe eigene Methoden, um von dieser Seite alle Videos zu filtern, löschen, verschieben, etc. 
Darf meine eigene API Teile einer anderen API beinhalten? Ich denke mal nicht, oder? (wäre ja sonst schon etwas gemogelt..)



> Wenn du sowas rein aus Interesse probieren willst, kannst du ja am Anfang mal versuchen, einfache Formate wie .bmp zu reverse engineeren. bmp ist halt sehr, sehr einfach, aber du kannst schonmal lernen wie du rausfinden kannst, wie der Header aufgebaut ist. Und notfalls kannst du auch noch spicken


Gute Idee! Danke dir!


----------



## stg (12. Jul 2016)

Kababär hat gesagt.:


> Darf meine eigene API Teile einer anderen API beinhalten? Ich denke mal nicht, oder? (wäre ja sonst schon etwas gemogelt..)



Das kommt einzig und allein auf die Lizenzrechte drauf an. Beachte außerdem, dass du bei Änderungen in der/den genutzten APIs aufkommende Änderungen "nachziehen" musst.
Ansonsten: Natürlich! Solche Abhängigkeiten sind das normalste der Welt..



Baldur hat gesagt.:


> POI ist ja wahrscheinlich deshalb so komplex, weil es versucht möglichst viele Features abzudecken, die .doc bietet.


Und POI ist - Achtung Unwort! - historisch gewachsen.


----------



## Baldur (12. Jul 2016)

Kababär hat gesagt.:


> Bis vorhin war mir irgendwie nicht so ganz klar, dass es für jede Datei wirklich so strikte Vorgaben bezüglich des Aufbaus bzw. eine öffentliche Dokumentation gibt.
> Hätte ja sein können, dass man dafür Lizenzen braucht oder so, damit nicht jeder einfach APIs bauen kann.


Da liegt ja der Hund begraben  Es steht natürlich jedem frei, ob er die Beschreibung seiner Dateiformate veröffentlicht oder nicht. Gerade bei proprietären Programmen wie MS Office, o.ä. ist es keine Seltenheit, daß die Formate nicht öffentlich dokumentiert sind, um es der Konkurrenz schwerer zu machen. Reverse Engineering ist dann eben der einzige Weg. Wie das rechtlich ausschaut weiß ich grad gar nicht - ich glaube das war eher eine Grauzone und es haben schon Hersteller versucht da mit Urheberrecht dagegen vorzugehen.



Kababär hat gesagt.:


> Darf meine eigene API Teile einer anderen API beinhalten? Ich denke mal nicht, oder? (wäre ja sonst schon etwas gemogelt..)


Wie stg schon schrieb kommt das letztendlich auf die Lizenz drauf an. Ohne jetzt nachgeschaut zu haben würde ich vermuten, daß Apache auch die Apache Lizenz verwendet, die eigentlich sehr frei ist.


----------



## Tobse (12. Jul 2016)

Ganz allgemein kann man den Ablauf von sowas wie folgt beschreiben:

1. Eine API / Library deckt immer Use-Cases ab. Man schreibt sowas nicht ins blaue hinen. Daher erster Schritt: Welche Funktionen soll deine API bereitstellen? Dateien lesen, wie genau soll der Inhalt gelesen werden können, was soll modifiziert werden können?
2. Das Fachwissen erfassen. Bevor man eine API schreiben kann, muss man das zugrundeliegende nahezu vollständig verstanden haben. Es ist nich nötig, jedes Detail zu kenne aber je mehr, desto besser.
3. Eine Abstraktion schaffen: durch 2. weißt du jetzt, welche _Informationen_ in einer Datei X vorliegen und in welchem Datenformat. (Achtung: *Informationen != Daten*). Die Daten in der Datei musst du nun also in eine Logische Struktur bringen. Viele Dateiformate enthalten diese Struktur schon im Großteil (bspw. CSV: Zeilen, Spalten, Kopfzeile, ...). Auch das Encoding nicht vergessen 
4. Die Abstraktion als OOD abbilden: Die Struktur der Informationen wird jetzt von Klassen modelliert. _Ganz wichtig_: in diesem Schritt schreibst man am besten keine einzige Ziele Code! Man erstellt ein Klassendiagramm.
5. Das Klassendiagramm in Quellcode der gewünschten Programmiersprache übersetzen; _Auch hier wird kein einziger Methodenkörper befüllt!_
6. In TDD schreibt man jetzt die Tests gegen die zuvor erstellten Klassen. Ohne TDD passiert das parallel zum nächsten Schritt.
5. Des in 5. erstelle Grundgerüst kann nun Implementiert werden (Code kann in die Leeren Methodenkörper geschrieben werden). Bei komplexen Dateiformaten (bspw. .doc, odt, PDF, MPEG, ...) ist das _viel zu viel_ für einen einzelnen Programmierer.

Eine vernünftige Library steht und fällt mit den Schritten 1-3. Wenn da gepfuscht und schnell-schnell gemacht wird, kommt ein nutzloses Stück Scheisse bei raus.

P.S.: Bei 4. ist es unabdingbar, dass der Code, welcher Dateien ließt und schreibt, 100% von dem Code getrennt ist, welcher den Dateiinhalt abbildet. An sonsten kann man keine sinnvollen Tests schreiben und deine Library hat am Ende mehr Bugs als LOC.
P.P.S: Wenn du das mal selbst üben willst, empfehle ich dir Dateiformate wie CSV oder Markdown als Anfang. Das schafft man alleine in kurzer Zeit.
P.P.P.S.: APIs beschäftigen sich logischerweise nicht immer mit Dateien. Für andere Libraries oder Server-Schnittstellen (bspw. Rest-APIs) ist der Prozess fast komplett anders.


----------

