Metamorph erweitern

Metamorph kann mit eigenen Java-Klassen oder Javascript-Funktionen erweitert werden. Während im Kapitel “Transformationen” bereits die beiden entsprechenden Morph-Funktionen, java und script, vorgestellt wurden, werden an dieser Stelle Hinweise zur Implementation gegeben. Da dies weniger mit Metamorph selbst als mit der API von Metafacture zu tun hat, befindet sich dieses Kapitel im Anhang.

Erweitern mit einer Java-Klasse

Das Metafacture-Framework stellt im Paket org.metafacture.metamorph-api verschiedene abstrakte Klassen zur Verfügung, um Metamorph mit eigenen Java-Klassen zu erweitern:

Die Prozessierung des Literalwertes erfolgt jeweils durch die Methode protected String process(String value), die den Literalwert entgegennimmt und den modifizierten zurückgibt. Durch setter-Methoden kann Instanzen dieser Klasse eine beliebige Anzahl an Argumenten mitgegeben werden (vgl. dazu die Metamorph-Funktion java).

Folgend ein Beispiel für eine neue zustandslose Metamorph-Funktion, welche Strings mit dem ROT13-Algorithmus enkodiert:

package org.swissbib.linked;

import org.metafacture.metamorph.api.helpers.AbstractSimpleStatelessFunction;

public class Encoder extends AbstractSimpleStatelessFunction {

    private String algorithm = "ROT13";

    public void setAlgorithm(String name) {
        this.algorithm = name;
    }

    @Override
    protected String process(String value) {
        StringBuilder result = new StringBuilder();
        switch (algorithm) {
            case "ROT13":
                for (char c : value.toCharArray()) {
                    if (c >= 65 && c <= 90) {
                        result.append(rotate(c, (char) 65, (char) 90));
                    } else if (c >= 97 && c <= 122) {
                        result.append(rotate(c, (char) 97, (char) 122));
                    } else {
                        result.append(c);
                    }
                }
        }
        return result.toString();
    }

    private char rotate(char c, char min, char max) {
        if ((c + 13) > max) {
            return (char) (c + 13 - max + min - 1);
        } else {
            return (char) (c + 13);
        }
    }
}

Erweitern mit einer Javascript-Funktion

Die Javascript-Funktion muss ein Argument - den Wert des Literals - entgegennehmen können und ein Wert eines beliebigen Typs zurückgeben. Die die Funktion aufrufende Java-Klasse wendet dann die toString()-Methode auf den Rückgabewert an und gibt den Wert an die verarbeitende Metamorph-Funktion zurück. Ein Beispiel:

// script.js
// Funktioniert nur für Strings mit ASCII-Zeichen!
function asciiReverse(val){
  return val.split("").reverse().join("");
}

In Metamorph wird die Funktion folgendermassen aufgerufen:

<data source="litA">
  <!-- Pfade sind relative zur Basis-URI -->
  <script file="script.js" envoke="asciiReverse"/>
</data>