2019.06 2020.06

URIResolver in MyCoRe

URIResolver sind ein Standard-Erweiterungsmechanismus für XSLT. Damit können anwendungsspezifische Methoden aufgerufen oder weitere Daten (XML) in den XSLT-Verarbeitungsprozess integriert werden.

Da die XSLT-Verarbeitung in MyCoRe-Anwendungen eine bedeutende Rolle spielt, stellt das MyCoRe-Framework wesentliche Funktionalität für die Verarbeitung und Presentation von (XML-)Daten in Form von URIResolvern bereit. Besonders der Layout-Prozess macht davon häufigen Gebrauch.

URIResolver können in XSLT innerhalb document(), xsl:import oder xsl:include genutzt werden, um dynamisch erzeugtes XML innerhalb XSLT-Verarbeitungsprozess bereitzustellen und weiterzuverarbeiten.

Die Auswahl einer konkreten URIResolver-Implementierung erfolgt durch ein spezifisches Schema bzw. den Protokoll-Bestandteil einer URI. So liefert z.B. mcrobject:mir_mods_00001234 das Metadaten-XML eines konkreten MyCoRe-Objektes zurück.

Die Klasse org.mycore.common.xml.MCRURIResolver implementiert das Interface java.xml.transform.URIResolver und verwaltet die verschiedenen durch MyCoRe und seinen Komponenten bereitgestellten URIResolver. MyCoRe-Anwendungen können diesen Mechanismus nutzen, um eigene URIResolver bereitzustellen.

Folgende URI-Resolver werden durch MyCoRe bereitgestellt:

mycore-base

webapp:{path}

liest eine (XML-)Datei aus dem Dateisystem der Web-Applikation. Der Pfad der zu lesenden Datei wird relativ zum Wurzelverzeichnis der Web-Applikation angegeben. Der Zugriff erfolgt direkt, d.h. ohne zusätzlichen HTTP-Request.

1
  webapp:config/labels.xml

mycore-base

resource:{path}

liest eine (XML-)Datei aus dem CLASSPATH der Web-Applikation, d.h. die Datei befindet sich in der Regel im Verzeichnis WEB-INF/classes/ oder in einer der jar-Dateien im Verzeichnis WEB-INF/lib/ der Web-Anwendung

Da MyCoRe den CLASSPATH erweitert, kann die Datei auch von anderen Stellen eingelesen werden,
z.B. aus dem resources-Unterordner im MyCoRe-Konfigurationssverzeichnis.

1
  resource:ContentStoreSelectionRules.xml

mycore-base

session:{key}

liest ein XML-Element, das als JDOM-Element in der aktuellen MCRSession abgelegt ist.

Mittels der put() Methode der Klasse MCRSession kann analog zu einer Java-Hashtable unter einem Schlüssel ein Objekt in der Session abgelegt werden. Ein Servlet kann darüber z.B. ein JDOM-Element in der MCRSession ablegen und den Schlüssel einem Stylesheet über einen XSL-Parameter mitteilen. Der MyCoRe-Editor oder Layout-Service kann dieses JDOM-Element dann mittels des URIResolvers aus der Session auslesen.

1
  session:my-xml-object

Das Beispiel liest das JDOM XML-Element ein, das als Ergebnis von MCRSessionMgr.getCurrentSession().get("my-xml-object"); zurückgegeben wird.

mycore-base

mcrobject:{mcrObjectId}

liest die XML-Darstellung der Metadaten eines MyCoRe-Objektes mit der angegebenen MyCoRe-Objekt-ID aus.

1
  mcrobject:mir_mods_07910401

mycore-base

mcrfile:{mcrDerivateId}/{path}

liefert eine Datei aus einem MyCoRe-Derivate zurück, welche über den Pfad adressiert ist.

1
  mcrfile:mir_derivate_00000001/folder1/image2.jpg

mycore-base

fileMeta:{mcrDerivateId}/{path}

liefert die File-Metadaten (z.B. URNs) aller Dateien im Derivate oder einer konkreten Datei zurück (siehe MCRFileMetadata).

Der Parameter {path} ist optional.

1
2
  mcrfileMeta:mir_derivate_00000001
  mcrfileMeta:mir_derivate_00000001/folder1/data2.xml

ifs:{derivateId}/{path}

liefert die Verzeichnisstruktur eines Derivates zurück.
Derzeit einzige Implementierung ist eine mcrdirectory-Verzeichnisstruktur im XML-Format.

Der Parameter {path} ist optional.

1
2
  ifs:mir_derivate_00000001
  ifs:mir_derivate_00000001/folder2

mycore-base

deletedMcrObject:{mcrObjectId}

gibt die letzte Version der MyCoRe-Metadaten eines gelöschten MyCoRe-Objektes zurück (sofern ein versionierender Metadaten-Store eingesetzt wird).

1
  deletedMcrObject:mir_mods_07910401

mycore-base

classification:{classificationQuery}

gibt eine Klassifikation in unterschiedlichen Formaten aus. Es wird eine Vielzahl von Konfigurationsmöglichkeiten unterstützt.

1
 classification:{editor['['formatAlias']']|editorComplete|metadata}:{Levels}[:noEmptyLeaves]:{parents|children}:{ClassID}[:CategID]

Die einzelnen Parameter sind durch Doppelpunkte getrennt.

  1. Der erste Parameter bestimmt den Formattyp der Rückgabe.
    • editor bereitet die Klassifikation für die Nutzung in der Editor-Selectbox auf. Letztere kann für den Label-Text noch unterschiedliche Formatanweisungen enthalten, die mit [formatAlias] referenziert werden.
      Das Property MCR.URIResolver.Classification.Format.{formatAlias} enthält dann die Formatieranweisung.
      Diese besteht aus beliebigem Text kombiniert mit Platzhaltern:
      • {id} steht für die Kategorie-ID,
      • {count} steht für die Zahl der zugeordneten MyCoRe-Objekte,
      • {text} steht für das Attribut text im label-Tag der Klassifikationsdefinition,
      • {description} steht für das Attribut description im label-Tag der Klassifikationsdefinition.
    • 1
      
        MCR.URIResolver.Classification.Format.textDescription={text} - {description}
    • editorComplete bereitet die Klassifikation für die Nutzung in der Editor-Selectbox auf. Dabei wird die für die SOLR Suche erforderliche Notation für den value ClassID:CategID verwendet.
    • metadata gibt die Klassifikation im MyCoRe-XML-Format aus.
  2. Levels gibt an, wieviel Hierarchiestufen dargestellt werden. Bei Angabe der CategID ist dies die Anzahl der Kindkategoriehierarchiestufen.
    Ist Levels „-1“ angegeben, so bedeutet dies „komplette Hierarchie“.
  3. noEmptyLeaves ist ein optionaler Parameter. Wenn angegeben, werden leere Kategorien ohne Objekte nicht mit ausgegeben. Diese Funktion ist nur für den Rückgabetyp editor bzw. editorComplete , d.h. sinnvollerweise in Suchmasken, implementiert.
  4. parents oder children gibt an, ob bei Angabe einer CategID zusätzlich alle übergeordneten Kategorien mit zurückgegeben werden (parents) oder ob nur die Kinder der Kategorie berücksichtigt werden sollen. Bei Angabe eines positiven Levels und „parents“ werden sowohl die Eltern ausgegeben, wie auch {Levels} Hierarchieebenen der Kinder.
  5. ClassID ist die Klassifikations-ID
  6. CategID ist Kategorie-ID

1
2
3
  classification:editor[textDescription]:-1:children:PACS
  classification:editorComplete:3:noEmptyLeaves:children:DDC:09
  classification:metadata:0:parents:mir_institutes:Unis.Jena

Mit dem Property MCR.URIResolver.Classification.Sort.{ClassID} kann gesteuert werden, ob die Label in der zurückgelieferten Klassifikation alphabetisch sortiert ausgegeben werden sollen (default=true). Mit dem Wert false wird die interne Sortierung (Reihenfolge der Knoten im XML) verwendet.

mycore-base

access:action={permission}&object={mcrObjectId}

liest die XML-Darstellung der ACL-Metadaten für ein MyCoRe-Objekt aus und gibt diese als XML-Darstellung im Format der servacls aus.

  • Mit dem Parameter action=all werden alle Permissions für das MyCoRe-Object zurückgeliefert. Alternativ kann eine konkrete Permission angegeben werden.

1
2
  access:action=all&object=mir_mods_07910401
  access:action=writedb&object=mir_mods_07910401

mycore-base

checkPermission:{id}:{permission} / checkPermission:{permission}

gibt true oder false zurück ,je nach dem, wie die Permission für ein Objekt für den aktuellen Benutzer gesetzt ist. Im zweiten Fall wird geprüft, ob eine übergebene Permission zulässig ist oder nicht.

1
2
3
4
5
   checkPermission:{id}:{permission}
   checkPermission:MIR_mods_00000001:read
   
   checkPermission:{permission}
   checkPermission:{create-class}

erzeugt:
1
  <boolean>true</boolean>
mycore-base

localclass:{class}?{param}

Dieser URIResolver läd eine Java-Klasse und leitet den Aufruf daran weiter.
Die Klasse muss einen URIResolver implementieren, dessen resolve()-Methode aufgerufen wird.

1
 localclass:org.mycore.ClassName?mode=getAll

mycore-base

buildxml:{params}

generiert aus den Parametern ein XML-Objekt.

  • Das Root-Element wird als Parameter _rootName_={root_element_name} angegeben.
  • Der Rest der XML-Struktur wird mittels XPath-Ausdrücken definiert

1
  buildxml:_rootName_=mycoreobject&amp;metadata/parents/parent/@href=mir_mods_4711
erzeugt:
1
2
3
4
5
6
7
  <mycoreobject>
    <metadata>
      <parents>
        <parent href="mir_mods_4711" />
      </parents>
    </metadata>
  </mycoreobject>

und

1
  buildxml:_rootName_=mods:mods&amp;mods:identifier=10.123/456&amp;mods:identifier/@type=doi
erzeugt:
1
2
3
  <mods:mods>
    <mods:identifier @type="doi">10.123/456</mods:identifier>
  </mods:mods>

mycore-base

language:{code}

kann verwendet werden, um zwischen verschiedenen Codes für eine Sprache zu konvertieren. Das zurückgegebene XML enthält die ISO 639-1 und ISO 639-2 Sprachcodes für die angefragte Sprache.

1
  language:de

erzeugt folgendes XML:

1
  <language xmlCode="de" biblCode="ger" termCode="deu" />

mycore-base

basket:{typeID}:{basketID}

liefert Einträge aus dem Warenkorb der Session in einer MyCoRe-Anwendung.
Der Resolver wird z. B. für den Input des Warenkorb-Editors genutzt.

  • Die typeID beschreibt den Typ des Korbes.
    In der Session können mehrere Körbe mit verschiedenen typeID existieren. Bisher ist nur die ID objects in Gebrauch.
  • Die basketID ist eine konkrete Warenkorb-ID.
    Sie hat in der Standardimplementierung die Form einer MCRObjectID.

1
2
 
  basket:objects:MyCoRe_basket_00000001

mycore-base

versioninfo:{mcrObjectID}

liefert Versionierungsinformationen über ein MyCoRe-Objekt im XML-Format. Ist die Versionierung abgeschaltet, wird nur eine Versionszeile mit den Datum der letzten Änderung ausgegeben.

1
  versioninfo:MyCore_document_00000001

erzeugt folgendes XML:

1
2
3
4
  <versions>
    <version user="editor" date="2015-06-19" r="12345" action="update"/>
    ...
  </versions>

mycore-base

xslInclude:{include_name}

Erzeugt ein XSL-Stylesheet, dass weitere Stylesheets inkludiert. Welche definiert das MCR.URIResolver.xslIncludes.{include_name} Property. Zu Laufzeit können so weitere XSL-Dateien hinzugeladen werden, um zusätzliche Templates bereitszustellen oder vorhandene zu Überschreiben.

1
  MCR.URIResolver.xslIncludes.components=iview.xsl,wcms.xsl
1
  <xsl:include href="xslInclude:components"/>

erzeugt folgendes XML:

1
2
3
4
<xsl:stylesheet version="1.0">
 <xsl:include href="iview.xsl"/>
 <xsl:include href="wcms.xsl"/>
</xsl:stylesheet>

Startet import_name mit dem Prefix class., werden die href-Attribute von einer Klasse bereitgestellt, die das Interface org.mycore.common.xml.MCRURIResolver.MCRXslIncludeHrefs implementiert.

1
  MCR.URIResolver.xslIncludes.class.template=org.foo.XSLHrefs
1
  <xsl:include href="xslInclude:class.template"/>
mycore-base

xslImport:{import_name}:{xsl_file}

erzeugt ähnlich wie "xslInclude" ein XSL-Stylesheet, jedoch werden nicht alle XSL-Dateien inkludiert, sonder in einer Kaskade importiert. Das ermöglicht die Erweiterung bestimmter Templates mittels <xsl:apply-imports />, um z.B. zusätzliche Felder bei der SOLR-Indizierung zu erzeugen.
Die Liste wird im Property MCR.URIResolver.xslImports.{import_name} definiert.

1
  MCR.URIResolver.xslImports.components=third.xsl,second.xsl

1
   <xsl:import href="xslImport:components:first.xsl"/>

mycore-base

redirect:{alias}

liest das Alias-Property aus und leitet die Daten an die URL weiter, welche im Property MCR.URIResolver.redirect.{alias} definiert ist.

1
2
 MCR.URIResolver.redirect.{alias}={href}
 MCR.URIResolver.redirect.alias=webapp:path/to/alias.xml
mycore-base

notnull:{uri}

Dieses Präfix für eine andere URI stellt sicher, dass es bei Aufruf der genannten URI keine NullPointerException gibt. Sollte es bei Verarbeitung der anhängenden URI eine Exception geben, wird diese geloggt. Im Falle einer Exception oder wenn die URI den Wert NULL zurückgibt, liefert dieser Resolver stattdessen eine leere XML-Datei. Dies ist z.B. hilfreich, um in XSL Stylesheets URIs zu verwenden, aber gegen Fehler abzusichern.

1
2
 notnull:{uri}
 notnull:mcrobject:mir_mods_07910401
mycore-base

catchEx:{uri}

Dieses Präfix für eine andere URI stellt sicher, dass es bei Aufruf der genannten URI keine Exception gibt. Tritt eine Exception auf, wird diese abgefangen und als XML ausgegeben.

1
2
 catchEx:{uri}
 catchEx:mcrobject:mir_mods_07910401
mycore-base

xslStyle:{stylesheets}?{params}:{uri}

Dieses Präfix für andere URI wendet das Stylesheet [stylesheet] auf die XML-Auagabedatei der nachfolgenden URI an und gibt das Ergebnis als XML zurück.

Das Stylesheet befindet sich im Classpath der Anwendung. Die Extension .xsl entfällt im Parameter {stylesheet}. Es ist möglich, Parameter zu übergeben und der Ausgabe von einem Stylesheet gleich an ein zweites zu weiterzuleiten.

1
2
  xslStyle:{stylesheet},{stylesheet}{?param1=value1{&amp;param2=value2}}:{anyMyCoReURI}
  xslStyle:mycoreobject-mods,mods2dc?derivate=mycore_derivate_00000001:mcrobject:mycore_doc_00000001

In diesem Beispiel würde das MyCoRe-Objekt zuerst in ein MODS-Dokument umgewandelt, und anschließend nach Dublin-Core transformiert werden.

mycore-base

xslTransform:[TransformParms]

Dieses Präfix funktioniert wie xslStyle. Nur wird ein definierter MCRContentTransformer verwendet, statt einer vordefinierten Liste von Stylesheets. Im Gegensatz zu xslStyle ist das Verhalten also noch weiter konfigurierbar und prinzipiell nicht auf "XSL" beschränkt.

1
2
  xslTransform:{stylesheet}[?param1=value1[&amp;param2=value2]...]:{anyMyCoReURI}
  xslTransform:mycoreobject-txt:file:object.txt
mycore-base

i18n:{message_property}

liefert eine einzelne Übersetzung oder eine Liste von Übersetzungen für die aktuelle Sprache zurück. Bei einzelnen Properties wird eine verkürzte Form zurückgegeben. Andernfalls erfolgt die Rückgabe mittels Liste. Für einzelne Properties kann auch eine Parameterisierung erfolgen. Parameter werden im Property mit {nummer} angegeben.

1
2
3
4
5
6
  i18n:{property | property* | property{*}, property{*}, ...}
  i18n:myapp.user.login
  i18n:myapp.user*
  i18n:myapp*,mycore*
  i18n:{þroperty}:{parameter}[:{parameter}...]
  i18n:myapp.parameter:param1:param2 für myapp.parameter={0} und {1}
1
  <i18n>Hier geht es zum Login</i18n>
1
2
3
4
5
 <i18n>
   <translation key="myapp.user.password">Passwort</translation>
   <translation key="myapp.user.login">Hier geht es zum Login</translation>
   ...
 </i18n>
mycore-base

data:{DataURLParams}

liefert den Inhalt einer Data-URL zurück.

1
2
3
 data:[mime-type[;param1=value1[;param2=value=2]]]{,content}

 data:text/html;charset=utf-8,%3Ch1%3EHello%20MyCoRe!%3C%2Fh1%3E
mycore-base

file:{path}

lädt eine physische Datei vom Server.

1
  file:/home/mcradmin/data.xml
mycore-base

http:{path} / https:{path}

lädt eine Ressource aus dem Internet. Sie wird serverseitig gecached.

1
  https://www.mycore.de/classifications/state.xml
mycore-acl

accesskeys:{mcrObjectId}

Gibt alle Zugriffsschlüssel für ein Objekt im JSON-Format zurück, zusätzlich mit count Attribute für die Anzahl der Zugriffsschlüssel.

mycore-base

crypt:{encrypt/decrypt}:{cipherid}:{value}

Verschlüsselt oder entschlüsselt einen String und gibt das Ergebniss in einem xml Dokument zurück. Dieses xml Dokument enthält einen einzigen Knoten, den Wurzelkoten value.

1
  <xsl:value-of select="document('crypt:decrypt:keyabstract:LDIIKk4wTJP32R8QRrwXHw==')/value" />

MCRURIResolverFilter

Der MCRURIResolverFilter liefert, bei XML- oder HTML-Output und wenn der Log-Level von MCRURIResolver auf DEBUG steht, Debug-Informationen als Kommentar im Quelltext, welche URIs während der Erstellung aufgerufen worden sind. In der richtigen Reihenfolge und ggf. auch mit Referrer. Da er standardmäßig mit eingebunden ist, muss man bis auf besagten Log-Level nichts konfigurieren.

Erweiterung des URI-Resolvers

Unter Umständen kann es nötig sein den URIResolver für eigene Anwendungen zu erweitern. Dabei ist es nicht möglich vorhandene URI-Schemas zu überschreiben, jedoch neue den bereits vorhandenen hinzuzufügen. Für jedes Schema z.B. file gibt es einen Resolver, der entsprechende URIs auflösen kann. Dieser Resolver muss die Schnittstelle MCRURIResolver.MCRResolver im Paket org.mycore.common.xml implementieren. Für die Zuweisung eines Schemas zur MCRResolver -Implementierung ist der MCRResolverProvider verantwortlich, der diese Schnittstelle aus MCRURIResolver implementiert. Letzterer stellt eine Abbildung von Schema-Strings zu MCRResolver -Instanzen zur Verfügung. Der MCRResolverProvider kann also beliebig viele MCRResolver zu den bereits in MyCoRe integrierten hinzufügen. Eingebunden wird ein zusätzlicher MCRResolverProvider mittels folgendem Property MCR.URIResolver.externalResolver.class = {voller Klassenname}