GSB 7.0 Standardlösung

Content-Erweiterungen

Das Rest-Interface des GSB Editors stellt einen Satz an „Standardfunktionen“ für Operationen auf GSB-Resourcen (Dokumente, Ordner) zur Verfügung. Hierzu zählen einfache Operationen wie Ausleihen, Speichern eines Dokumentes oder auch komplexere Operationen wie Zurückgeben eines Dokumentes in Verbindung mit einer Validierung des Dokumentinhalts.

Der Editor stellt für die oben skizzierten Operationen entsprechende Funktionalitäten zur Verfügung, die bei der redaktionellen Arbeit der Redakteure im GSB implizit bei Aufruf der entsprechenden Operationen ausgeführt werden.

Einzelne Operationen können im aktuellen Stand des GSB Editors über die Dokumenttypkonfiguration in einem gewissen Rahmen erweitert werden. Für einzelne Properties eines Dokumenttyps kann bspw. aus einem Katalog von vorhandenen Initialisierern eine Vorbelegung einer Property mit einem definierten Wert beim Neuanlegen eines Dokumentes durchgeführt werden. Ähnliches gilt für Validatoren, die beim Zurückgeben eines Dokumentes genutzt werden, um den Wert einer Dokumentproperty auf „Gültigkeit“ zu prüfen.

Eine einfache Möglichkeit der mandantenspezifischen Erweiterung der Operationen des GSB Editors sind auf Basis der Content-Erweiterungen umsetzbar. Der GSB Editor stellt "Hook" zur Verfügung, die durch die Content-Erweiterungen für funktionale Erweiterungen eines Mandanteneditors genutzt weden können. Die Hooks können als Pre- bzw. Post-Action zu einer Standardoperation ausgeführt werden.

Darüber hinaus stehen auch Content-Erweiterungen für die Umsetzung mandantenspezifischer Validierungen und Initialisierungen zur Verfügung.

Die Content-Erweiterungen sind einfach in einen Mandanten integrierbar, indem diese im Content des Madanten (genauer in der Editorkonfiguration) abgelegt werden.

Konfiguration

Die mandantenspezifischen Erweiterungen werden im Content des Mandanten von berechtigten SiteAdmins angelegt und aktualisiert.

Die Dokumente werden als Groovyskript wie skizziert im Content des Mandanten definiert, um diese einfach durch einen berechtigten SiteAdmin anpassen zu können. D.h. die Dokumente müssen der Groovy Spezifikation genügen (s.a. http://docs.groovy-lang.org/latest/html/documentation/#_groovy_language_specification). Darüber hinausgehende Dokumentationen finden sich auf der Groovy-Homepage (s.a. http://groovy-lang.org/). Die GSB spezifischen Methoden können der GSB Api-Dokumentation (Javadoc) entnommen werden.

Das Basisverzeichnis für die Ablage der Dokumente ist /SiteGlobals/_extensions/scripts (s.a. folgender Screenshot).

Ablagestruktur Content-Erweiterungen Ablagestruktur Content-Erweiterungen

Unterhalb des Scripts-Ordners werden die mandantenspezifischen Skripte abgelegt. Bei der Ablage und Benennung der Dokumente muss sichergestellt werden, dass

  • diese über alle Mandanten eindeutig sind sowie
  • die Konventionen der Benennung der in der Einleitung skizzierten Standardfunktionalitäten eingehalten wird.

Die mandantenspezifischen Skripte werden im Content des Mandanten unterhalb des „scripts“-Ordners im Ordner de/bund/gsb/customers/<CUSTOMER>/webeditor abgelegt. In diesem Ordner befinden sich

  • Initialisierer im Ordner initializer,
  • Validatoren im Ordner validator sowie
  • Actions werden im Ordner action abgelegt.
Achtung:
Da es sich bei den Content-Erweiterungen um "Basiskonfigurationen" des GSB-Mandanten handelt, empfiehlt es sich diese über eine geeignete Rechtedefinition zu schützen. Die Erweiterungen sollten weder für Redakteure noch für SiteAdmins lesbar sein, um ungewollte/-berechtigte Änderungen durch diese Gruppen ausschließen zu können. Stattdessen sollte eine neue Gruppe (bspw. Basiskonfiguration) angelegt werden. Dieser Gruppe sollten nur Personen zugeordnet sein, die über entsprechende fachliche und technische Kenntnisse zu Funktionen und Schnittstellen der Content-Erweiterungen und die technische Einbettung in den Redaktionsprozess verfügen. So kann sichergestellt werden, dass nur kundige und berechtigte Personen ein Zugriff und Anpassung der Content-Erweiterungen ermöglicht wird.

Pre- und Post-Actions

Der Editor unterstützt verschiedene Aktionen (Actions) auf Dokumenten und Ordner. So können bspw. Dokumente gespeichert, ausgeliehen u. zurückgegeben werden. Um diese Actions mandantenspezifisch zu erweitern, werden im Content des Mandanten sogenannte Pre- und Post-Actions definiert. Die Pre-Actions werden vor der Ausführung der eigentlichen Editor-Action ausgeführt und die Post-Actions nach der eigentlichen Action. So können fachliche Anforderungen des Mandanten einfach umgesetzt werden, ohne das hierfür die Standardfunktionalität des Editors angepasst werden muss. Die Definition der Pre- und Post-Actions erfolgt jeweils in einem dedizierten Dokument. Die Actions implementieren ein Pre- bzw. PostProcessor-Interface. Ein Interface ist eine Art Schnittstellenbeschreibung und definiert im Falle der Pre-/Post-Actions die Operationen die bereitgestellt werden müssen (s.a. http://groovy-lang.org/objectorientation.html#_interface).

Die folgende Definition zeigt dies exemplarisch anhand der Post-Action des Mandanten standardlsg:

@GroovySpringBeanpublic class standardlsgEditorOperationPostProcessor implements EditorOperationPostProcessor {}

Die einzelnen Methoden des Interface werden dann noch mit der gewünschten mandantenspezifischen Implementierung versehen. Das folgende Codefragment skizziert dies exemplarisch anhand der „getFolder“-Action.

@Overridepublic Folder getFolder(Folder folder)
{
try {
// _config-Ordner unterhalb von /standardlsg/SiteGlobals/DoNotDelete dürfen nicht gelöscht werden
if (folder.getName().startsWith("_config") &&
folder.getPath().startsWith("/standardlsg/SiteGlobals/DoNotDelete")) {
folder.getActions().remove("DELETE");
}
}
catch (Exception e) {
// Fehlerbehandlung
}
return folder;
}

Aus fachlicher Sicht verhindert die skizzierte Action, dass _config-Ordner unterhalb des Pfades /standardlsg/SiteGlobals/DoNotDelete nicht gelöscht werden können, indem dynamisch das Delete-Recht für diese Ordner entfernt wird.

Die skizzierte Action stellt an dieser Stelle nur ein synthetisches Beispiel dar in dem die prinzipiellen Möglichkeiten durch Definition einer entsprechenden Action im Content des Mandanten skizziert wird. Der Katalog möglicher Actions kann der folgenden Grafik entnommen werden:

Verfügbare Actions Verfügbare Actions

Methoden, die nicht mit einer mandantenspezifischen Implementierung versehen werden sollen, werden wie folgt implementiert:

@Overridepublic List<Document> getDocuments(List<Document> documents) {
return null;
}

Die Implementierung der betreffenden Methode ist bis auf das Return-Statement leer.

Initialisierer

Initialisierer werden vom GSB Editor beim Anlegen eines neuen Dokumentes ausgeführt, um einzelne Dokumentproperties vorzubelegen. Um individuelle Anforderungen eines Mandanten an die Initialisierung von Dokumentproperties einfach umzusetzen, werden diese direkt im Content des Mandanten abgelegt.

Initialisierer werden ähnlich wie die im vorherigen Kapitel skizzierten Pre-/Post-Actions definiert. Die Definition eines mandantenspezifischen Initialisierers erfolgt wie folgt:

@GroovySpringBeanpublic class TestInitializer implements PropertyInitializer {}

Der Initialisierer TestInitializer implementiert das Interface PropertyInitializer. Die eigentliche Logik des Initialisierers wird dann in der Methode initialize implementiert:

@Overridepublic void initialize( final Map<String,DocumentProperty> properties,
final Property propertyConfig,
final Initializer initializer,
final Document document) {
DocumentPropertyStringValue value = DocumentPropertyStringValue.create();
value.setValue(initializer.getText());
final DocumentProperty property = new DocumentProperty(propertyConfig.getName(), value);
properties.put(propertyConfig.getName(), property);
}

Aus fachlicher Sicht liest der Initialisierer den Wert des Attributs text in der Dokumenttypdefinition des Editors aus und schreibt diesen in die betreffende Property des Dokuments. Der Initialisierer wird wie folgt in die Editor-Konfiguration eingebunden:

<Property name='keywords' type='String' col='12' visible='true'> <Initializer class='TestInitializer' text="Vorbelegung Keywords"/> </Property>

Mit dieser Definition wird bei neu angelegten Dokumenten die Dokument-Property keywords mit dem statischen String „Vorbelegung Keywords“ initialisiert.

Der skizzierte Initialisierer stellt an dieser Stelle nur ein synthetisches Beispiel dar, in dem die prinzipiellen Möglichkeiten durch Definition eines entsprechenden Initialisierers im Content des Mandanten skizziert werden. Weitere Einsatzszenarien für mandantenspezifische Initialisierer sind bspw.

  • die automatische Erstellung von zugeordneten fremdsprachigen Dokumenten beim Anlegen eines neuen Dokumentes für die Hauptsprache des Mandanten und Verlinkung der verschiedenen Sprachdokumente und
  • eine dynamische und kontextspezifische Initialisierung von Properties beim Neuanlegen eines Dokumentes. Im deutschen Bereich (Ordner /DE) wird das Sprachkennzeichen mit deutsch und im englischen Bereich (Ordner /EN) mit englisch vorbelegt.

Validatoren

Validatoren werden beim Zurückgeben eines Dokumentes (Abschluss einer redaktionellen Bearbeitung) genutzt, um die Werte einzelner Dokumentproperties zu prüfen. So können mit Hilfe der Validatoren sowohl syntaktische (bspw. Pflichtfeld/Zeichenkette nicht leer) als auch semantische (bspw. Zeichenkette enthält einen erlaubten Wert) Prüfungen vorgenommen werden. Um individuelle Anforderungen eines Mandanten an die Validierung von Dokumentproperties einfach umzusetzen, sollen dies direkt im Content des Mandanten abgelegt werden können.

Ein Validator wird ähnlich wie die im vorherigen Kapitel skizzierten Initialisierer definiert. Die Definition eines mandantenspezifischen Validators erfolgt wie folgt:

@GroovySpringBeanpublic class TestValidator implements PropertyCheckinValidator {}

Der Validator TestValidator implementiert das Interface PropertyCheckinValidator. Die eigentliche Logik des Validators wird dann in der Methode validate implementiert:

@Overridepublic void validate(Object target,
Validator validator,
Document document, String propertyName,
Errors errors) {
if (target instanceof DocumentProperty) {
DocumentProperty property = (DocumentProperty) target;
if (property.getPropertyValue() != null) {
final String value = property.getPropertyValue().toString();
if (value.equalsIgnoreCase("error")) {
errors.rejectValue(propertyName, ERROR_CODE, (String[]) [ "TestValidator" ], TESTVALIDATION_MESSAGE);
}
}
}
}

Aus fachlicher Sicht prüft der skizzierte Validator, dass in der zugeordneten Property nicht die Zeichenkette „error“ vorhanden ist. Ist dies der Fall, dann wird ein Validierungsfehler erzeugt und das Zurückgeben des Dokumentes verhindert. Der Validator wird wie folgt in die Editor-Konfiguration eingebunden:

<Property name='keywords' type='String' col='12' visible='true'>
<Validator class='TestValidator'/>
</Property>

Mit dieser Definition wird beim Zurückgeben eines Dokumentes die keywords-Property geprüft. Die Validierung wird mit dem oben skizzierten TestValidator durchgeführt.

Der skizzierte Validator stellt an dieser Stelle nur ein synthetisches Beispiel dar, in dem die prinzipiellen Möglichkeiten durch Definition eines entsprechenden Validators im Content des Mandanten skizziert werden. Ein weiteres Einsatzszenario für einen mandantenspezifischen Validator ist bspw. eine kontextbezogene Validierung beim Zurückgeben von Dokumenten bei dem das Sprachkennzeichen anhand des Ablagepfades (/DE → deutsch, /EN → englisch) geprüft wird.