Tutorial: Wie baue ich ein eigenes Framework für Oxygen XML?

Seit 2012 wird von der TELOTA-Initiative an der Berlin-Brandenburgischen Akademie der Wissenschaften »ediarum« entwickelt und eingesetzt. Dabei handelt es sich um ein Paket aus drei Softwarelösungen (Oxygen XML, eXistdb und ConTeXt), das es Wissenschaftlern in verschiedenen Editionsvorhaben ermöglicht, ihre Ergebnisse in TEI-XML zu bearbeiten, zu speichern und zu präsentieren. Damit die Eingabe und Bearbeitung möglichst komfortabel und einfach geschieht, wird als Eingabeoberfläche in ediarum die proprietäre Software Oxygen XML Author eingesetzt. Diese Software hat den Vorteil, dass die Bearbeiter nicht mehr direkt im XML-Code arbeiten, sondern in einer benutzerfreundlichen Oberfläche, die zum einen die XML-Datei optisch aufbereitet präsentiert und zum anderen Werkzeugleisten bereitstellt, mit denen per Knopfdruck XML-Elemente eingefügt bzw. Textteile ausgzeichnet werden können.

Da jedes XML-Schema andere Elemente verlangt, gibt es in Oxygen XML Author natürlich nicht die eine Werkzeugeleiste. Stattdessen werden sog. Frameworks (auch »Dokumenttypzuordnungen« genannt) benutzt. In ihnen werden die Ansichten und Werkzeugleisten definiert, die auf eine ganz bestimmte Sorte von XML-Dokumenten angewendet werden können. Oxygen XML liefert einige Frameworks für weit verbreitete XML-Schemata schon mit, so z.B. für Docbook und DITA – oder eben für die TEI. Viel spannender ist aber die Möglichkeit, selbst eigene Frameworks zu erstellen, die genau für das eigene XML-Schema passen und maßgeschneiderte Werkzeugleisten und Ansichten mitbringen. Dieses Tutorial gibt Ihnen einen Überblick darüber, wie ein solches Oxygen-Framework erstellt wird.

Empfohlene Voraussetzungen für dieses Tutorial
  • Vorkenntnisse: XML, XPATH, CSS
  • Software: Oxygen XML

Schritt 1 – Ein Oxygen-Framework anlegen

oxy_framework_tutorial_005Die Frameworks in Oxygen finden wir im Menü Optionen > Einstellungen unter dem Punkt »Dokumenttypen-Zuordnung«. Anfangs sehen wir dort nur alle mit Oxygen XML Author zusammen gelieferten Frameworks. Wir möchten aber ein eigenes neues anlegen – das können wir unten über die Schaltfläche »Neu« tun.

Im nun erscheinenden Fenster legen wir neben Namen und Beschreibung, vor allem den Speicherort fest. Damit wir das Framework nämlich am Ende weiterverteilen können, speichern wir es »extern«.  Dazu erstellen wir im Programmordner im Unterordner frameworks einen neuen Ordner, dem wir den Namen unseres Frameworks geben, z.B. »briefedition-xyz«. In diesem Ordner können wir dann die eigentliche »Framework option file« mit der Dateiendung ».framework« speichern, die unsere Frameworkkonfiguration enthält. Es handelt sich dabei eigentlich um eine einfache XML-Datei, die wir aber auch bequem über das Dialogfenster in Oxgen XML Author bearbeiten können. Dadurch, dass wir sie extern gespeichert haben, können wir sie am Schluss anderen zur Verfügung stellen.

Danach stellen wir noch den internen Bearbeitungsmodus auf »Autor«. Dadurch werden alle XML-Dateien automatisch erstmal in der Autoransicht geöffnet und nicht in der Codeansicht.

Wichtig: Vergessen Sie nicht, im Dialogfenster »Dokumenttypen« auf »OK« zu klicken, damit die Veränderungen gespeichert werden! Das sollten Sie im übrigen auch mehrmals während der Arbeit am Framework tun.

Über die Tabs können wir nun unser Framework konfigurieren. In diesem Tutorial folgen wir weitgehend der Anordnung der Tabs von links nach rechts.

Schritt 2 – Verknüpfungsregeln

oxy_framework_tutorial_006Mit Hilfe der Verknüpfungsregeln werden Frameworks einem Dokumenttyp zugeordnet. Das kann z.B. anhand des Dateinamens oder des Wurzelelements geschehen. Da wir derzeit stets mit TEI-Dateien arbeiten und Konflikte vermeiden wollen, benutzen wir bei TELOTA mittlerweile ein eigens für diesen Zweck geschaffenes Attribut telota:doctype im Wurzelelement TEI der XML-Dateien. Das schließt aus, dass das Framework aus Versehen für andere Dateien benutzt wird.

Schritt 3 – Schema einbinden

oxy_framework_tutorial_008Es ist wichtig – nicht nur für Oxygen XML –, dass ein Schema für die XML-Dateien vorliegt. Nur dadurch kann Oxygen zum einen die Dateien korrekt mit CSS darstellen (dazu später mehr) und zum anderen die Eingabe des Benutzers validieren. Der einfachste Weg ist es, die URL des Schema in der XML-Datei zu notieren. Dann steht das Schema allerdings nicht zur Verfügung, wenn offline gearbeitet wird. Um das zu verhindern kann man in Oxygen im Tab »Validierung« eine Validierung anlegen, die man dann als Standard definiert, der automatisch zur Prüfung verwendet wird. Diese Standardvalidierung kann auf ein lokal gespeichertes Schema verweisen (etwa im Frameworksordner) und ignoriert auch ein evtl. im Dokument notiertes Schema.

Schritt 4 – Dateivorlagen

Damit die XML-Dateien nicht jedesmal von Grund auf neu geschrieben werden müssen, können im Framework Dateivorlagen hinterlegt werden. Dazu legen wir im Ordner frameworks/briefedition-xyz einen Unterordner »templates« an und tragen diesen Pfad im Tab »Vorlagen« ein. Wenn wir dort nun XML-Dateien ablegen, werden diese unter ihrem Dateinamen dem Benutzer beim Erstellen einer neuen Datei zur Auswahl angeboten. In den Dateivorlagen können übrigens Oxygen-Editorvariablen benutzt werden.

Tipp: In den meisten Pfadangaben, die Sie im Framework machen müssen, können Sie verschiedene Variablen benutzen. So lautet z.B. der Pfad zu den Dateivorlagen ${frameworkDir}/briefedition-xyz/templates – die Variable „frameworkDir“ steht hier für den kompletten Pfad zum Frameworksverzeichnis der Oxygeninstallation. Welche Variablen Sie nutzen können erfahren Sie meistens durch einen Klick auf das Symbol rechts neben dem Pfadeingabefeld.

Schritt 5 – CSS

Kern eines Oxygen-Frameworks ist der Tab »Autor«. Dort können wir in der Rubrik CSS ein Stylesheet verknüpfen, mit dem die XML-Dateien angezeigt werden sollen. Wir können auch mehrere Stylesheets hinterlegen, die dem Benutzer zur Auswahl angeboten werden. Dadurch ist es möglich, für bestimmte Arbeitsschritte bestimmte Elemente oder Attribute hervorzuheben bzw. Auszublenden.

Oxygen XML Author unterstützt einen großen Teil der CSS-Spezifikationen. Nicht unterstützt werden vorwiegend positionierungsrelevante CSS-Anweisungen. Einen detaillierten Überblick über die Unterstützung findet man in der Dokumentation im Abschnitt »CSS Support in Author«.

Aber Oxygen unterstützt nicht nur die gängigen CSS-Formatierungen, sondern auch viele eigene CSS-Eigenschaften, die ebenfalls in der Dokumentation aufgelistet werden, z.B.:

Darüber hinaus bietet Oxygen eigene Funktionen an, die in vielen CSS-Eigenschaften eingesetzt werden können und sehr viel möglich machen. So kann z.B. aus einem Attributwert mit mehreren verschiedenen Identifikationsnummern die passende herausgeholt, beschnitten und in einem Link weiterverwendet werden.

Sehr mächtig ist die Möglichkeit, mit Hilfe der Oxygen-CSS-Eigenschaften Formulare zu bauen – auch und gerade, um Attribute mit Werten zu versehen.

Schritt 6 – Werkzeugleiste bauen

Kern des Frameworks sind die »Aktionen«, die durch eine Schalftläche – sei es in einer Werkzeugleiste, im Menü oder im Kontextmenü – ausgelöst werden. Für jedes vom Bearbeiter einzufügende Element (mitsamt Attributen und Kindelementen) muss eine Aktion angelegt werden. Wir wollen das an zwei Beispielen demonstrieren.

Beispiel 1: Schaltfläche zum Auszeichnen einer Textänderung

In der Briefedition sollen von den Bearbeitern bei der Transkription auch diejenigen Stellen im Text ausgezeichnet werden, bei denen der Autor im Manuskript erst ein Wort durchgestrichen und es durch ein anderes ersetzt hat. In TEI-XML könnte das z.B. so aussehen:

<subst>
	<del rend="struck-through">bin</del>
	<add place="above">sind</add>
</subst>

oxy_framework_tutorial_011Nach dem Anlegen einer neuen Aktion sind ID, Name und Beschreibung der Aktion auszufüllen, außerdem können kleine Grafiken als Symbol für die Schaltfläche eingebunden werden. Der Hauptbestandteil einer Aktion sind allerdings die »Vorgänge«. Ein Vorgang besteht aus einer Bedingung, die in XPATH notiert ist sowie einer Javaoperation mitsamt ihren zu setzenden Argumenten. Für eine Aktion (d.h. Schaltfläche) kann man mehrere Vorgänge anlegen (ein großer Vorteil, wie wir im nächsten Beispiel sehen werden).

Die Bedingung kann man in diesem Fall dazu verwenden, dass der Vorgang nur ausgeführt wird, wenn sich der Cursor innerhalb von tei:text befindet (und nicht etwa im teiHeader). Da unsere Aktion nur diesen einen Vorgang enthalten wird, wird Oxygen (ab Version 14.2) die Schaltfläche ausgrauen, wenn dem nicht so ist. Die Bedingung können wir dann als XPath so notieren:

ancestor-or-self::text

Danach können wir (im Feld untendrunter) die Javaoperation auswählen, also den eigentlichen Einfüge- bzw. Auszeichnungsvorgang definieren. Oxygen liefert schon Javaoperationen für die meisten Anwendungsfälle mit. Für unseren Fall ist »Surround with Fragment« nützlich, da wir vllt. nicht nur einfach das Element an der Stelle des Cursors einfügen, sondern einen markierten Text damit umgeben wollen. Wir wählen also diese Javaoperation aus. Danach sehen wir die zu setzenden Argumente. Wichtig ist hier vor allem das erste Argument, dass aus dem XML-Code besteht, den wir einfügen wollen. Ihn können wir nach einem Doppelklick auf das Feld bequem eintragen.

Wenn Sie Namensräume benutzen, müssen Sie den Namensraum im Attribut @xmlns im obersten Element mit angeben.

Sie können Attribute mit festen Werten einsetzen oder aber den Benutzer nach diesen Werten fragen. Dafür steht in Oxygen XML die Editorvariable ask bereit. Mit ihr können wir den Benutzer auffordern, einen frei wählbaren Wert einzugeben. In vielen Fällen möchten wir ihn aber eher aus einer Liste von Werten wählen lassen. Das ist mit derselben Variable auch möglich – und empfehlenswert. Darüber hinaus ist es mit weiteren Editorvariablen möglich, automatisch das aktuelle Datum oder eine generierte Identifikationsnummer zu setzen. In der Oxygen-XML-Dokumentation finden Sie eine Übersicht aller Variablen.

Unser Beispiel sieht dann wie folgt aus:

<subst xmlns="http://www.tei-c.org/ns/1.0">
  <del rend="${ask('Art der Löschung', combobox, ('struck-through':'Durchgestrichen';'overwritten':'Überschrieben';'':'';), 'struck-through')}"></del>
  <add place="${ask('Ort der Hinzufügung', generic)}"></add>
</subst>

Jetzt nur noch bestätigen und unsere erste Aktion ist erstellt. Diese können wir nun je nach Bedarf in das Menü, das Kontextmenü oder eine Toolbar (»Symbolleiste«) einfügen. Dieser Abschnitt sollte selbsterklärend sein, aber ein Hinweis zum praktischen Einsatz kann nicht schaden: es ist sinnvoll im Menü alle Aktionen zu hinterlegen. In den Werkzeugleisten dann nur die wichtigsten und im Kontextmenü nur wenige, oft benutzte Aktionen, für die die Platzierung des Cursors relevant ist.

Beispiel 2: Schaltfläche zum Einfügen eines Strukturelement

Im Gegensatz zum ersten Beispiel, wo wir lediglich einen per Cursor markierten Textabschnitt ausgezeichnet haben, möchten wir nun ein sog. Strukturelement einfügen. Ein Element also, dass an einer einzigen, ganz bestimmten Stelle im XML-Baum notiert wird. In unserem Fall möchten wir z..B. den Absender, den Empfänger und das Schreibdatum in teiHeader/profileDesc notieren. Das könnte so aussehen:

<creation>
	<date when="1808-01-02" cert="high"/>
	<persName type="absender" key="p216">Blanc, Ludwig Gottfried </persName>
	<persName type="empfänger" key="p1914">Schleiermacher, Friedrich Daniel Ernst</persName>
</creation>

Alle drei Elemente sowie das Elternelement creation sollen erst vom Bearbeiter hinzugefügt werden – und jedes für sich. Als Beispiel schauen wir uns die Aktion an, die den Absender einfügt – also das mittlere Element persName. Hier haben wir nun das Problem, dass wir folgende Varianten der vorhandenen XML-Strkutur beim Einfügen bedenken müssen:

  1. Das Element creation ist (samt Kindelementen natürlich) gar nicht vorhanden
  2. Das Element creation ist vorhanden, nicht jedoch das Kindelement date
  3. Das Element creation und das Kindelement date sind vorhanden

Abhängig vom jeweiligen Szenario ändert sich natürlich das einzufügende XML-Snippet und/oder die Position des einzufügenden XML-Snippet. Wir möchten aber keine drei Schaltflächen erstellen, sondern lediglich eine einzige. Unser Vorteil ist nun, dass wir pro Aktion mehrere Vorgänge anlegen und sie jeweils von Bedingungen abhänging machen können. Im konkreten Beispiel  ergeben sich daher folgende Varianten:

Vorgang 1:
Bedingung, dass Element creation nicht vorhanden ist:
not(//teiHeader/profileDesc/creation)
Ausgelöster Vorgang: Fügt creation mitsamt des Kindelementes persName[@type='absender'] als erstes Kindelement von profileDesc ein. Wir benutzen hier (und in den beiden anderen Varianten) die Java-Operation »InsertFragmentOperation«, die es uns erlaubt einen Einfügeposition relativ zu einem anderen ebenfalls wählbaren Element definieren.

Vorgang 2:
Bedingung, dass Element creation vorhanden ist, nicht jedoch date:
//profileDesc/creation and not(//creation/date)
Ausgelöster Vorgang: Fügt persName[@type=’absender‘] als erstes Kindelement von creation ein.

Vorgang 3:
Bedingung, dass Element creation und Kindelement date vorhanden sind:
//profileDesc/creation and //profileDesc/creatioin/date
Ausgelöster Vorgang: Das Element persName[@type=’absender‘] wird nach dem Element date eingefügt.

Zu beachten ist beim Anlegen mehrerer Vorgänge noch deren Ausführungspriorität. Es wird nämlich nur derjenige Vorgang ausgeführt, dessen Bedingung zuerst erfüllt sind. Daher ist bei der Formulierung der Bedingungen auch darauf zu achten.

oxy_framework_tutorial_013An diesem Beipsiel wird deutlich, dass wir mit ein und derselben Schaltfläche drei verschiedene Einfügevorgänge abdecken können, ohne dass der Nutzer sich darüber Gedanken machen muss. Wenn wir jetzt noch allen Bedingungen //creation/persName[@type='absender'] hinzufügen, sorgen wir außerdem dafür, dass nur ein einzier Absender angelegt werden kann und ansonsten die Schaltfläche nicht zur Verfügung steht (d.h. ausgegraut angezeigt wird).

Die so erstellten Aktionen können nun im selben Tab in das Menü, das Kontextmenü oder eine Werkzeugleiste eingefügt werden.

Neben den standardmäßig in Oxygen XML vorhandenen Java-Operationen hat TELOTA für seine Lösung »ediarum« noch einige weitere Operationen programmiert, die u.a. den gleichzeitigen Zugriff auf einen Index ermöglichen. Wir haben diese Java-Operationen mittlerweile zur Verfügung gestellt und erläutern in einem eigenen Tutorial die Implementierung von Indexfunktionen.

Schritt 7 – Verpacken und verteilen

Wenn wir unser Oxygen-Framework fertig gestellt und getestet haben, möchten wir es den Benutzern zur Verfügung zu stellen. Dafür steht in Oxygen XML seit der Version 14.0 das »Add-on«-Feature bereit, mit dem man Frameworks über einen Webserver an Oxygen XML Installationen ausliefern und später auch updaten kann. Das funktioniert so:

  1. Den Ordner framworks/briefedition-xyz als ZIP-Datei packen
  2. Die ZIP-Datei auf einen Webserver hochladen
  3. Auf dem Webserver eine XML-Datei mit einem bestimmten Format (siehe Beispieldateien zu diesem Tutorial) anlegen und dort die Angaben zum Framework ergänzen. Am wichtigsten ist hier die Versionsnummer und der Pfad zur ZIP-Datei
  4. In einer Oxygen-XML-Installation unter Optionen > Einstellungen > Add-Ons die URL der XML-Datei eintragen
  5. Über Hilfe > Add-Ons verwalten kann man nun alle über diese URL verfügbaren Add-ons installieren oder updaten. Hat man in den Einstellungen (siehe vorhergehenden Punkt) das entsprechende Kästchen angehakt, wird man auch automatisch über Updates informiert.

Dadurch können zukünftig Updates schnell und unkompliziert ausgeliefert und vom Benutzer selbst aktualisiert werden.

Wie geht’s weiter?

Dieses Tutorial sollte nur einen ersten Überblick über die Erstellung eines Oxygen-Frameworks geben. In der offziellen Dokumentation von Oxygen XML finden Sie ausführliche Informationen zu diesem Thema. Außerdem ist geplant, demnächst weitere Tipps und Blogartikel zu ediarum veröffentlichen.

Download

Das im Beispiel angelegte Oxygen-Framework können Sie sich hier herunterladen. Darin enthalten ist auch eine Beispiel-XML-Datei für die Bereitstellung des Frameworks als »Add-On« auf einem Webserver.

Update 29.01.2015: Korrigierte Version des Oxygen-Frameworks für dieses Tutorial hochgeladen.

Kommentare

11 Kommentare zu “Tutorial: Wie baue ich ein eigenes Framework für Oxygen XML?”

  1. Tutorial: Wie baue ich ein eigenes Framework für Oxygen XML? | DHd-Blog am Oktober 30th, 2013 13:51

    […] eigene (TEI-)XML-Schema passen und maßgeschneiderte Werkzeugleisten und Ansichten mitbringen. Das Tutorial auf digiversity gibt einen Überblick darüber, wie ein solches Oxygen-Framework erstellt […]

  2. Zusätzliche Javaoperationen für Oxygen XML Frameworks veröffentlicht — digiversity am Dezember 16th, 2013 10:42

    […] sofort sind zusätzliche Javaoperationen für Oxygen XML Frameworks als Java-Archive (JAR) und als Quellcode zur freien Verwendung verfügbar. Die Javaoperationen […]

  3. Tutorial: Indexfunktionen für Oxygen XML Frameworks — digiversity am Dezember 16th, 2013 10:44

    […] Basiert auf dem Tutorial: Wie baue ich ein eigenes Framework für Oxygen XML? […]

  4. Indexfunktionen in Oxygen XML Frameworks (Tutorial & Download) | DHd-Blog am Dezember 16th, 2013 10:56

    […] hat nun die im Rahmen von ediarum entwickelten zusätzlichen Javaoperationen für Oxygen XML Frameworks als Java-Archive (JAR) und als Quellcode auf github zur Verfügung gestellt. Sie ergänzen die […]

  5. Sandro am Mai 10th, 2016 15:01

    Liebes Ediarum-Team,

    ich versuche gerade nach diesem Tutorial eigene Aktionen zu kreieren. Weder werden mir die Icons aus der ediarum.jar noch mein eigenes angezeigt.

    Haben Sie vielleicht eine Idee, was ich vergessen haben könnte.

    Mit herzlichen Grüßen
    Sandro Schwarz

  6. Sandro am Mai 10th, 2016 15:20

    Wenn ich das TEI-framework um meine Aktion erweitere funktioniert es.

  7. Stefan Dumont am August 1st, 2016 14:08

    Lieber Sandro,

    ich sehe leider jetzt erst Deinen Kommentar. Schick uns doch eine kurze Mail (siehe http://www.bbaw.de/die-akademie/mitarbeiter/dumont), falls das Problem weiterbestehen sollte. Wir helfen gerne weiter.

    Beste Grüße
    Stefan Dumont

  8. LexaLag am Mai 25th, 2017 21:31

    Вольво (Volvo) замена масла в АКПП со скидкой 40 %Замена масла акпп Вольво (Volvo)До окончания акции осталось:
    Замена масла в акпп Вольво имеет ограниченный срок действия. Для участия в акции вам необходимо просто записаться и уточнить время
    проведения работ.Выберите удобный для вас офис — метро Полежаевское или город Мытищи.Качественно выполненная замена масла, качественным
    маслом + гарантии + скидки. Ваша машина будет счастлива. доверяйте только профессионалам. Никаких скрытых наценок, только точная цена,
    только скидки!Цена у официалов цена у конкурентов Наша цена по акции Современные автоматические коробки передач Volvo очень технологичны
    и имеют сложную конструкцию. Их стоимость весьма значительна
    (более 200 тысяч рублей). По этим причинам АКПП современных автомобилей Вольво (Volvo) требуют более ответственного и квалифицированного
    отношения к своему обслуживанию.МАСЛО+РАБОТА=Узнай свою цену.
    Автоматические трансмиссии автомобилей в России работают в более тяжелых условиях, чем в Европе. Исследуя особенности работы масла в
    коробке Вольво (Volvo) в различных регионах, крупнейшие производителя трансмиссий пришли к выводу, что в России переключения передач
    происходит в два раза чаще.Это объясняется: переменчивым уровнем дорог относительно горизонта (спуски, подъемы) движение автомобиля
    в пробках (частые переключения N-1-2) высокая интенсивность движения по автомагистралям (обгоны)Важные функции в работе Вашего Вольво
    играет масло в коробке автомат, обеспечивающее правильность и долговечность работы коробки передач. Оно передает усилие на исполнительные
    механизмы, смазывает и охлаждает трущиеся поверхности. Оно регулярно находится под высоким давлением и температурами.
    Под воздействием этих факторов масла volvo окисляются, разрушается заводской пакет присадок. В нем теряются смазывающие, вязкостные и
    чистящие свойства. При больших перепадах температур в масла попадает конденсат, который также негативно влияет на его качестве.
    Фрикционы – основной элемент в АКПП Вольво (Volvo) для передачи крутящего момента. В процессе эксплуатации они изнашиваются, и абразивные
    частицы попадают в масла. Когда это происходит, масло АКПП сильно темнеет и появляется запах гари. Абразивные частицы, циркулируя по
    масляным каналом в коробке передач, приводят к выходу из строя блока гидравлических клапанов и других компонентов.
    Эксплуатация коробки передач с горелым, потерявшим свои свойства маслом, приводит к её преждевременному выходу из строя, поэтому вашему
    volvo необходима замена масла.Ремонт АКПП Вольво (Volvo) – от 110 тысяч рублей, замена на новую – более 250 тысяч рублей, замена масла
    — примерно 18 000 тысяч рублей.Первые симптомы неисправности АКПП: рывки при переключении R-D толчки при разгоне и ускорении
    рывки при переключении на пониженную передачу посторонний звук(гул) при движении из АКПП Замена масла акпп Вольво поможет избежать
    проблем, связанных с неправильной работой коробки передач на Вашем Вольво (Volvo).Как показывает наш опыт, на пробегах 40 — 80 тысяч
    километров (в зависимости от условий эксплуатаций) на автомобилях Вольво замена масла в коробке становится актуальна, поскольку масло
    теряет свои свойства.Что касается продолжительности данной процедуры — замена масла в АКПП Вольво занимает как правило около 2 часов.

  9. Aliskaesofe am Mai 25th, 2017 23:44

    This hot hungarian blonde with round and big boobs is being fucked in her wet vagina by a big penis. The guy is fucking her more and more deeper later after that he start to lick her ass and finger her nice pussy. He also penetrate her from her back and the bitch is now more closer to the orgasm. Brittany likes to masturbate using water. Yes, any kind of water, be it the chlorine filled outdoors swimming area, the bath tub, and especially the shower head! Pointing the running water coming out of the shower, she positions it so that her pussy gets to be tickled! What a resourceful lady! All versed bitches start early and amaze with their hidden skills. This young blonde-haired lady wearing pigtails is hardly waiting to impress her lover. She gets on knees to please him with an unforgettable dream blowjob. The slutty babe wears fishnet stockings and white lace panties which are a huge turn on. They should study for their exams, but all they do is fuck like crazy! Look at them how bored they are at the beginning and then, how things get out of control! The girls begin to suck cock, get their cunts licked and much more, so why not stick around and have some fun with these crazy college boys and girls! When you see Charlee’s blue eyes you can fall in love but when you see her gorgeous booty you just want to fuck her deep and hard. This beauty has a very sexy body, long legs, perfect ass, cute small tits and an angelic face that should be covered in hot semen. She is rubbing her shaved cunt on those stairways, will she get a hard dick in it? Its arty time for Lacey as she is getting drilled by a young cock. Without any concern of being outdoor, she is wrapping her juicy lips around her guy’s penis and gives a hell of a suck which has made him so horny that he keeps fucking her with her thighs wide until she moans with pleasure. Watch! Mommy Simone and Chase are two filthy whore that need a hard cock, hard as Johnny’s. These bitches play hard to get but as soon as Johnny takes out his rod, they start to drool! Chase is the first that has a taste and then Simone joins in. Now they share it like good girls but which one will receive the cum load?
    My crazy joker sex picture archive http://pussyxpic.com/
    dun6GjVTJ3k56ZYBe3j59v0P

  10. Williamelago am Mai 27th, 2017 15:46

    Atas syarikat-syarikat Forex diberi nilai dalam satu senarai dengan analisis daripada profesional fx-brokers-review.com/index_my.html

  11. JeffreyVeisy am Mai 28th, 2017 23:39

Schreibe einen Kommentar




Bitte auch die kleine Rechenaufgabe lösen (Spamschutz): *