Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 PHP-Metamodell: Erweiterungsmöglichkeiten • Zugriff auf Properties: • Properties beginnen mit „_“-Zeichen (z.B. $_name) • Lesezugriff von außen auf alle Properties (ohne vorangestelltes „_“-Zeichen wird durch Magic-Method MetaBase::__get($property) realisiert) • Unterklassenbildung • Namenskonvention für Unterklassen: $prefix_Meta<x> • Unterklassen müssen im selben Verzeichnis liegen • MetaModel::createModel($name, $prefix="") • Nur die Klassen müssen abgeleitet werden, die zusätzliche Funktionalität erhalten (siehe Folie 10) Andreas Schmidt PHP-Modell/Metamodell 1/10 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Klassendiagramm MetaBase __get($property) MetaType MetaModel _name _classes _relations _source _date createModel(name) addRelation($name) addClass($name) MetaClass _name _primary_key _attributes _relations _model MetaAttribute MetaRelationEnd _name _type _length _is_primary_key _class addAttributel(name, ...)getModel() addRelationEnd(name, ...) getModel() _role _type _min _max _class _relation_name _name _model MetaRelation _name _relation_ends _model addRelationEnd($end) Andreas Schmidt PHP-Modell/Metamodell 2/10 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Ableiten der Metaklassen warum ? • • • • Meta-API soll Domäne sehr gut abbilden zusätzliche Methoden/Properties erleichtern die Erstellung der Templates Templates bleiben besser lesbar und wartbar Jede Zielsprache hat ihre Eigenheiten (z.B. Bezeichnung von Datentypen, Programmiersprachkonstrukte, ...) • Pro Zielsprache eigenes Unterklassenmodul (z.B. SQL_Meta<x>, Java_Meta<x>, ...) Andreas Schmidt PHP-Modell/Metamodell 3/10 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Beispiel zur Unterklassenbildung: Definition Modell <?php include_once 'meta-model.php'; $model = MetaModel::createModel('Film DB'); $p = $model->addClass('Person'); $p->addAttribute('id','Integer',10,true); $p->addAttribute('name','String',30); $p->addAttribute('vor_name','String',30); $p->addAttribute('geburtstag','date'); $f = $model->addClass('Film'); $f->addAttribute('id', 'Integer',10, true); $f->addAttribute('titel', 'String',50); $f->addAttribute('jahr', 'date'); Andreas Schmidt PHP-Modell/Metamodell 4/10 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Beispiel zur Unterklassenbildung • zu generierender Code: class CRUD_Person { protected static $GET_ONE = " SELECT id, name, vor_name, geburtstag FROM Person WHERE id = ?"; protected static $INSERT = " INSERT INTO Person (id, name, vor_name, geburtstag) VALUES (?, ?, ?, ?)"; protected static $DELETE_ONE = "..."; protected static $DELETE_ALL = "..."; protected static $UPDATE = "..."; protected static $GET_ALL = "..."; Andreas Schmidt PHP-Modell/Metamodell 5/10 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 • Template: <?php foreach ($model->classes as $class): ?> class CRUD_<?php echo $class->name ?> { ... protected static $INSERT = " INSERT INTO <?php echo $class->name ?> (<?php for($idx=0; $idx < count($class->attributes); $idx++) { echo $class->attributes[$idx]->name; if ($idx < count($class->attributes)-1) echo ", "; } ?>) VALUES (<?php for($idx=0; $idx < count($class->attributes); $idx++) { echo "?"; if ($idx < count($class->attributes)-1) echo ", "; } ?>)"; ... Andreas Schmidt PHP-Modell/Metamodell 6/10 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 • Unterklasse class SQL_MetaClass extends MetaClass { function attribut_list($separator=",") { for($idx=0; $idx < count($this->attributes); $idx++) { echo $this->attributes[$idx]->name; if ($idx < count($this->attributes)-1) echo "$separator "; } } function parameters($separator=",", $with_pk=true) { for($idx=0; $idx < count($this->attributes); $idx++) { if ($with_pk || ! $this->attributes[$idx]->is_primary_key) { echo "?"; if ($idx < count($this->attributes)-1) echo "$separator "; } } } } Andreas Schmidt PHP-Modell/Metamodell 7/10 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Definition Modell <?php include_once 'meta-model.php'; sucht nach Unterklassen mit Prefix SQL_ $model = MetaModel::createModel('Film DB','SQL'); $p = $model->addClass('Person'); $p->addAttribute('id','Integer',10,true); $p->addAttribute('name','String',30); $p->addAttribute('vor_name','String',30); $p->addAttribute('geburtstag','date'); $f = $model->addClass('Film'); $f->addAttribute('id', 'Integer',10, true); $f->addAttribute('titel', 'String',50); $f->addAttribute('jahr', 'date'); Andreas Schmidt PHP-Modell/Metamodell 8/10 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 • neues Template: class CRUD_<?php echo $class->name ?> { ... protected static $INSERT = " INSERT INTO <?php echo $class->name ?> (<?php $class->attribut_list() ?>) VALUES (<?php $class->parameters() ?>)"; ... } <?php endforeach ?> Andreas Schmidt PHP-Modell/Metamodell 9/10 Fakultät für Informatik und Wirtschaftsinformatik MDSD - SS 2014 Anhang: Klassen Autoload Mechanismus # when working with subclasses, not declared subclasses are loaded # automatically or are silently created nicht vorhandene, # gesuchte Klasse function __autoload($class) { if (preg_match('#(\w+_)(Meta\w+)#', $class, $match)) { $file = $match[1].$match[2].".php"; existiert Datei mit entsprechendem Namen ? if (file_exists($file)) { # load class $class from '$file' include_once($file); wenn ja, laden } else { # create class $class instantly (no file $file found) eval ("class $class extends $match[2] {}"); } } } wenn nicht, dynamisch erzeugen (abgeleitet von entspr. Oberklasse) Andreas Schmidt PHP-Modell/Metamodell 10/10