The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Quiq::ContentProcessor - Prozessor für Abschnitts-Dateien

BASE CLASS

Quiq::Hash

SYNOPSIS

    use Quiq::ContentProcessor;
    
    $cop = Quiq::ContentProcessor->new('.mytool');
    $cop->registerType('MyTool::A','a','A','A');
    $cop->registerType('MyTool::B','b','B','A');
    ...
    $cop->load(@paths)->commit;
    
    for my $ent ($cop->entities) {
        $cop->msg($ent->name);
    }

DESCRIPTION

Ein Objekt der Klasse repräsentiert einen Prozessor für Entitäts-Dateien. Die Dateien bestehen aus einer Folge von Abschnitten, die von einem Abschnitts-Parser (s. Klasse Quiq::Section::Parser) geparsed und zu Abschnitts-Objekten instantiiert werden.

Der Prozessor delegiert die Verarbeitung der Abschnitts-Objekte an die per registerType() registierten Entitäts-Klassen (Plugin-Schnittstelle). Diese bauen aus den Abschnitts-Objekten Entitäts-Strukturen auf, aus denen die Ausgabedateien generiert werden. Die Entitäts-Klassen sind nicht Teil des ContentProzessors.

Bei Anwendung der Operation commit() wird der Quelltext jeder Entität gegen den Stand im Storage verglichen. Im Falle einer Änderung wird die Entität als geändert gekennzeichnet, d.h. ihre Ausgabedateien müssen neu generiert werden.

Das Resultat der Ausführung ist eine Menge von Entitäts-Objekten plus ihrem Änderungs-Status. Die Menge der Entitäts-Objekte kann mit der Methode entities() abgefragt werden.

Universelles Plugin

Ein Universelles Plugin kann definiert werden, indem bei registerType() nur $pluginClass und $extension als Argumente angegeben werden. An diese Plugin-Klasse werden alle (Haupt-)Abschnitts-Objekte delegiert, für die kein Plugin definiert ist. Logischerweise kann es höchstens ein Universelles Plugin geben. Für ein Universelles Plugin findet keine Attribut-Validierung in der Basisklassenmethode create() statt. Das Konzept ist in erster Linie für allgemeine Programme wie z.B. Testprogramme gedacht.

Ausgaben

Der Umfang an Ausgaben wird mit der Konstruktor-Option -verbosity=>$level eingestellt. Default ist 1.

Die Methode msg() schreibt eine Ausgabe nach STDERR. Der erste Parameter gibt den Verbosity-Level an. Ist dieser größer als der eingestellte Verbosity-Level, unterbleibt die Ausgabe.

    $cop->msg(2,$text);

Ist kein Level angegeben, erfolgt die Ausgabe immer:

    $cop->msg($text);

Der Meldungstext $text kann printf-Formatelemente enthalten, diese werden wie bei printf durch die zusätzlich angegebenen Argumente ersetzt:

    $cop->msg($text,@args);

EXAMPLES

Füge alle Entitäts-Definitionen im Storage zu einem einzigen Datenstrom zusammen und schreibe diesen nach STDOUT (z.B. für Refactoring):

    $cop->load->fetch('-');

Übertrage alle Entitäts-Definitionen im Storage in Verzeichnis $dir (das Verzeichnis hat die gleiche Struktur wie das Verzeichnis def im Storage):

    $cop->load->fetch->($dir);

Liste alle Entitäten vom Typ $type auf:

    $cop->load;
    for my $ent ($cop->entities($type)) {
        $cop->msg($ent->name);
    }

METHODS

Konstruktor

new() - Instantiiere ContentProcessor-Objekt

Synopsis

    $cop = $class->new($storage,@opt);

Arguments

$storage

Das Storage-Verzeichnis, z.B. '.storage'.

Options

-verbosity => 0|1|2 (Default: 1)

Umfang der Laufzeit-Meldungen.

Returns

ContentProcessor-Objekt

Description

Instantiiere ein ContentProcessor-Objekt und liefere eine Referenz auf dieses Objekt zurück.

Storage

storage() - Pfad zum oder innerhalb des Storage

Synopsis

    $path = $cop->storage;
    $path = $cop->storage($subPath);

Arguments

$subPath

Ein Sub-Pfad innerhalb des Storage.

Returns

Pfad

Description

Liefere den Pfad des Storage, ggf. ergänzt um den Sub-Pfad $subPath.

Plugins

registerType() - Registriere Entitäts-Typ

Synopsis

    $cop->registerType($pluginClass,$extension,$entityType,$sectionType,@keyVal);
    $cop->registerType($pluginClass,$extension); # universelles Plugin

Arguments

$pluginClass

Name der Plugin-Klasse, z.B. 'Program::Shell'.

$extension

Datei-Erweiterung für Dateien dieses Typs, ohne Punkt, z.B. 'prg'.

$entityType

Entitätstyp-Bezeichner, z.B. 'Program' oder 'Class/Perl'.

$sectionType

Abschnitts-Bezeichner ohne Klammerung, z.B. 'Program'.

@keyVal

Abschnitts-Attribute, die über den Abschnitts-Bezeichner hinaus den Dateityp kennzeichnen, z.B. Language=>'Perl'.

Returns

nichts

Description

Registriere Plugin-Klasse $pluginClass für Abschnitts-Objekte des Typs $sectionType und den Eigenschaften @keyVal.

Entsprechende Dateien werden an der Extension $extension erkannt. Als Typ-Bezeichner für Entitäten dieses Typs vereinbaren wir $entityType.

Die Plugin-Klasse wird automatisch geladen, falls sie noch nicht vorhanden ist (sie kann für Tests also auch "inline", d.h. im Quelltext des rufenden Code, definiert werden).

Die Plugin-Definition wird intern auf einem Hash-Objekt gespeichert, das vom ContentProcessor mit den instantiierten Entitäten verbunden wird.

Es kann auch ein Universelles Plugin definiert werden (siehe Abschnitt Universelles Plugin).

entityTypes() - Liste der Abschnitts-Typen

Synopsis

    @types | $typeA = $cop->entityTypes;

Returns

Liste von Abschnitts-Typen. Im Skalarkontext eine Referenz auf die Liste.

Description

Liefere die Liste der Abschnitts-Typen (Bezeichner), die per registerType() registriert wurden.

plugin() - Ermittele Plugin zu Abschnitts-Objekt

Synopsis

    $plg = $cop->plugin($sec);

Arguments

$sec

Abschnitts-Objekt

Returns

Plugin-Objekt

Description

Ermittele das Plugin zu Abschnitts-Objekt $sec. Existiert kein Plugin zu dem Abschnitts-Objekt, liefere undef.

Operationen

init() - Erzeuge Storage

Synopsis

    $cop = $cop->init;

Returns

ContentProcessor-Objekt (für Method-Chaining)

Description

Erzeuge den Storage, falls er nicht existiert. Existiert er bereits, hat der Aufruf keinen Effekt.

commit() - Übertrage Änderungen in den Storage

Synopsis

    $cop = $cop->commit(@opt);

Options

-incomplete => $bool (Default: 0)

Lade fehlende Entitäten aus dem Storage nach anstatt sie zum Löschen anzubieten.

Returns

ContentProcessor-Objekt (für Method-Chaining)

Description

Vergleiche den Quelltext jeder Entität gegen den Quelltext im Storage und übertrage etwaige Änderungen dorthin. Geänderte Entitäten werden in der Datenbank als geändert gekennzeichnet.

load() - Lade Entitäts-Definitionen

Synopsis

    $cop = $cop->load;
    $cop = $cop->load(@paths);

Arguments

@paths

Liste der Verzeichnisse und Dateien. Pfad '-' bedeutet STDIN.

Returns

ContentProcessor-Objekt (für Method-Chaining)

Description

Lade die Entitäts-Dateien der Pfade @paths. Ist @path leer, also kein Path angegeben, werden die Entitäts-Dateien aus dem Storage geladen.

Die Methode kann beliebig oft aufgerufen werden, aber nur der erste Aufruf lädt die Dateien. Alle weiteren Aufrufe sind Null-Operationen.

fetchToDir() - Hole Entitäts-Definitionen aus dem Storage

Synopsis

    $cop = $cop->fetchToDir($dir,$layout,@opt);

Arguments

$dir

Verzeichnis, in welches die Entitäts-Definitionen geschrieben werden.

$layout

Bezeichnung für das Verzeichnis-Layout. Dieser Parameter wird von filesToFetch() der Basisklasse nicht genutzt und ist daher hier nicht dokumentiert. Siehe Dokumentation bei den Subklassen.

Options

-overwrite => $bool (Default: 0)

Stelle keine Rückfrage, wenn Verzeichnis $dir bereits existiert.

Returns

ContentProcessor-Objekt (für Method-Chaining)

Description

Übertrage alle Entitäts-Definitionen in Verzeichnis $dir (oder nach STDOUT, s.u.) gemäß Layout $layout. Per Differenzbildung wird dabei ein konsistenter Stand hergestellt. Existiert Verzeichnis $dir nicht, wird es angelegt. Andernfalls wird eine Rückfrage gestellt, ob das Verzeichnis überschrieben werden soll (siehe auch Option --overwrite).

Wird als Verzeichnis ein Bindestrich (-) angegeben, werden die Entitäts-Definitionen nach STDOUT geschrieben.

Die Methode bezieht die zu schreibenden Dateien von der Methode filesToFetch(), an die der Parameter $layout weiter gereicht wird. Die Methode kann in abgeleiteten Klassen überschrieben werden, um andere Strukturen zu generieren.

Hilfsmethoden

filesToFetch() - Liste der Dateien für fetch

Synopsis

    @files = $cop->filesToFetch;
    @files = $cop->filesToFetch($layout);

Arguments

$layout

Bezeichner für eine bestimmte Abfolge und/oder Inhalt der Dateien.

Returns

Array mit zweielementigen Arrays

Description

Liefere die Liste der Dateien, die von den Methode fetchToDir() und [ANCHOR NOT FOUND]() geschrieben werden. Jede Datei wird durch ein zweielementiges Array repräsentiert, bestehend aus einem Datei-Pfad sowie dem Datei-Inhalt. Der Datei-Inhalt kann als String oder String-Referenz angegeben sein.

Diese (Basisklassen-)Methode liefert für jede Entität die Datei-Definiton

    [$ent->entityFile, $ent->sourceRef]

Damit erzeugt die Methode fetch() die gleiche Struktur wie der ContentProcessor im Storage-Verzeichnis def.

Die Methode kann in abgeleiteten Klassen überschrieben werden, um die Verzeichnisstruktur zu ändern und/oder den Inhalt der Dateien anders zusammenzustellen (z.B. mehrere Entity-Definitionen in einer Datei zusammenzufassen). In abgeleiteten Klassen können verschiedene Layouts durch das Argument $layout unterschieden werden.

Eingabedateien

extensionRegex() - Regex zum Auffinden von Eingabe-Dateien

Synopsis

    $regex = $cop->extensionRegex;

Returns

Kompilierter Regex

Description

Liefere den regulären Ausdruck, der die Dateinamen matcht, die vom ContentProcessor verarbeitet werden. Der Regex wird genutzt, wenn ein Verzeichnis nach Eingabe-Dateien durchsucht wird.

findFiles() - Finde Entitäts-Dateien in Verzeichnis

Synopsis

    @files | $fileA = $cop->findFiles($dir,@opt);

Arguments

$dir

Verzeichnis, das nach Dateien durchsucht wird.

Options

-noDotPaths => $bool (Default: 0)

Lasse Pfade, deren letzte Komponente mit einem Punkt beginnt, aus. Auf diese Weise verhindern wir, dass Dot-Verzeichnissse durchsucht werden.

Returns

Liste der Datei-Pfade (Strings). Im Skalarkontext eine Referenz auf die Liste.

Description

Durchsuche Verzeichnis $dir nach Entitäts-Dateien unter Verwendung des Regex, der von extensionRegex() geliefert wird.

parseFiles() - Parse Dateien zu Entitäten

Synopsis

    @entities | $entityA = $cop->parseFiles(@files);

Arguments

@files

Liste der Dateien. '-' bedeutet STDIN.

Returns

Liste der Entitäten. Im Skalarkontext eine Referenz auf die Liste.

processSubSection() - Verarbeite Sub-Abschnitt (abstrakt)

Synopsis

    $cop->processSubSection($fileEnt,$ent,$mainSec,$sec);

Arguments

$fileEnt

Entität, die Träger des gesamten Quelltextes ist. Diese ist im Quelltext mit [] gekennzeichnet.

$ent

Die aktuelle Entität. Kann identisch zu $fileEnt oder eine Sub-Entität (z.B. (File) oder (ProgramClass)) sein.

$mainSec

Die Entität oder Sub-Entität, der die mit <> gekennzeichneten Abschnitte zugeordnet werden.

$sec

Der aktuelle Abschnitt.

Returns

nichts

Entitäten

entities() - Liste der geladenen Entities

Synopsis

    @entities | $entityA = $cop->entities;
    @entities | $entityA = $cop->entities($type);

Arguments

$type

Abschnitts-Typ.

Returns

Liste von Entitäten. Im Skalarkontext eine Referenz auf die Liste.

Description

Liefere die Liste aller geladenen Entities oder aller geladenen Entities vom Typ $type. Bei der Abfrage der Entities eines Typs werden die Entities nach Name sortiert geliefert.

Persistente Information

needsTestDb() - Persistenter Hash für Test-Status

Synopsis

    $h = $cop->needsTestDb;

Returns

Hash-Referenz (persistenter Hash)

Description

Liefere eine Referenz auf den persistenten Hash, der den Status von Entitäten speichert.

needsUpdateDb() - Persistenter Hash für Entitäts-Status

Synopsis

    $h = $cop->needsUpdateDb;

Returns

Hash-Referenz (persistenter Hash)

Description

Liefere eine Referenz auf den persistenten Hash, der den Status von Entitäten speichert.

Ausgabe von Information

info() - Informationszeile

Synopsis

    $str = $cop->info;

Returns

Zeichenkette

Description

Liefere eine Informationszeile mit statistischen Informationen, die am Ende der Verarbeitung ausgegeben werden kann.

msg() - Gib Information aus

Synopsis

    $cop->msg($text,@args);
    $cop->msg($level,$text,@args);

Arguments

$level

Der Verbosity-Level, ab dem die Information ausgegeben wird.

$text

Text, der ausgegeben werden soll.

@args

Argumente, die für printf-Platzhalter in $text eingesetzt werden.

Returns

nichts

Description

Gib Information $text auf STDERR aus, wenn $level kleinergleich dem beim Konstruktor vorgebenen Verbosity-Level ist. Der Text kann printf-Platzhalter enthalten, die durch die Argumente @args ersetzt werden.

Zusätzlich wird der Platzhalter %T durch die aktuelle Ausführungsdauer in Sekunden ersetzt.

VERSION

1.148

AUTHOR

Frank Seitz, http://fseitz.de/

COPYRIGHT

Copyright (C) 2019 Frank Seitz

LICENSE

This code is free software; you can redistribute it and/or modify it under the same terms as Perl itself.