Poslední aktualizace: 23. června 2005
Tento dokument přináší základní přehled rámce ověření EMF a nabízí několik ukázek kódu k usnadnění implementace. Podrobnější popis všech funkcí EMF naleznete v publikaci EMF: Eclipse Modeling Framework, Second Edition (Addison-Wesley Professional, 2008), případně v dokumentaci Javadoc, kde jsou popsány přímo jednotlivé třídy struktury.
Chcete zajistit, aby data vašeho modelu odpovídala omezením, která pro ně platí? Tento přehled vám ve třech rychlých krocích nabídne představu o tom, jak toho můžete dosáhnout pomocí rámce ověření EMF.
|
Invariant - Implementuje se jako metoda třídy definovaná na modelu. Považuje se za "silnější" výrok platnosti než omezení. Např. hasUSState() |
Pojmenované omezení - Implementuje se jako metoda na externí třídě validátoru, nikoli na modelu samotném. Považuje se za "slabší" výrok platnosti než invariant. Např. NonNegativeQuantity, ValidShipDate |
Omezení na základě schématu - Stejné jako u pojmenovaného omezení, definuje se však v rámci schématu. Např. 'množství musí být hodnota typu int v rozmezí 0 až 100'. Protože je chování těchto typů omezení známé, nevyžaduje jejich implementace žádnou další práci: všechna omezení jednoduchého typu budou automaticky implementována generátorem kódu.
<xsd:element name="množství">
<xsd:simpleType>
<xsd:restriction base="xsd:int">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
|
| Krok 1: | Vytvořit omezení v modelu |
| Krok 2: | Definovat omezení |
| Krok 3: | Vygenerovat a spustit |
| Příloha: | Rozšířená témata |
Stejně jako u všech ostatních případů vývoje EMF můžete začít od anotovaného prostředí Java, schématu XML nebo modelů Rose. Metoda definování omezení závisí na zdroji modelu.
V případě modelu Rose stereotyp <<inv>> na operaci představuje invariant. Příklad viz Obrázek 1 výše.
Chcete-li přidat omezení pomocí produktu Rose 98, otevřete model a poté vyberte třídu (např. "Položka" ve zde uvedeném příkladu). Klepněte na ni pravým tlačítkem myši a vyberte volbu "Otevřít specifikaci" (nebo na "Položku" poklepejte). Poté vyberte kartu "Ecore", klepněte na pole omezení a přidejte omezení jako na Obrázku 2 výše.
Pro schéma můžete definovat omezení <xsd:restriction/> (viz výše) nebo pojmenované omezení:
<xsd:complexType name="Položka">
<xsd:annotation>
<xsd:appinfo source="http://www.eclipse.org/emf/2002/Ecore"
ecore:key="constraints">
NonNegativeQuantity ValidShipDate
</xsd:appinfo>
</xsd:annotation>
... </xsd:complexType>
Pro anotované prostředí Java můžete definovat invarianty a omezení takto:
|
Invariant
/**
* @model
*/
public interface USAddress
{
... /**
* @model
*/
boolean hasUSState(
DiagnosticChain diagnostics,
Map context);
... }
|
Omezení
/**
* @model
annotation="http://www.eclipse.org/emf/2002/Ecore
constraints='NonNegativeQuantity ValidShipDate'"
*/
public interface Item
{
... }
|
Naimportujte model do EMF, poté vygenerujte kód jako v Kroku 2 - 3 výukového programu Generování modelu EMF
Vygenerovaný kód bude vypadat asi takto:
|
Invariant, com.example.ppo.impl.USAddressImpl public boolean hasUSState(
DiagnosticChain diagnostics,
Map context)
{
// TODO: implementace této metody
// -> určete podmínku, která poruší
// invariant
// -> ověřte podrobnosti diagnostiky
// včetně závažnosti a zprávy
// Nezapomeňte odebrat značku @generated nebo
// ji označit jako @generated NOT
if (false)
{
if (diagnostics != null)
{
diagnostics.add(
new BasicDiagnostic(
Diagnostic.ERROR,
PPOValidator.DIAGNOSTIC_SOURCE,
PPOValidator.US_ADDRESS__HAS_US_STATE,
EcorePlugin.INSTANCE.getString(
"_UI_GenericInvariant_diagnostic",
new Object[] {
"hasUSState",
EObjectValidator.getObjectLabel(this,
context)}),
new Object [] { this }));
}
return false;
}
return true;
}
|
Omezení, com.example.ppo.util.PPOValidator public boolean validateItem_ValidShipDate(
Item item, DiagnosticChain diagnostics,
Map context)
{
// TODO implementace omezení
// -> určete podmínku, která poruší
// omezení
// -> ověřte podrobnosti diagnostiky
// včetně závažnosti, kódu a zprávy
// Nezapomeňte odebrat značku @generated nebo
// ji označit jako @generated NOT
if (false)
{
if (diagnostics != null)
{
diagnostics.add(
new BasicDiagnostic(
Diagnostic.ERROR,
DIAGNOSTIC_SOURCE,
0,
EcorePlugin.INSTANCE.getString(
"_UI_GenericConstraint_diagnostic",
new Object[] {
"ValidShipDate",
getObjectLabel(item, context) }),
new Object[] { item }));
}
return false;
}
return true;
}
|
Kód se také generuje ve validátoru, např. v com.example.ppo.util.PPOValidator, pro každý definovaný invariant, tyto metody však pouze delegují na metody invariantu na objektech samotných, např.:
public boolean validateUSAddress_hasUSState(USAddress usAddress,
DiagnosticChain diagnostics, Map context)
{
return usAddress.hasUSState(diagnostics, context);
}
V obou případech je třeba vygenerovaný kód ručně upravit a vysvětlit EMF, jak se má invariant nebo omezení implementovat. V prvním případě změňte řádek z:
if (false)
na
if ("US".equals(getCountry()) && getState() == null).
Po dokončení definování omezení spusťte nový pracovní prostor. Podrobnosti viz Krok 4 výukového programu Generování modelu EMF.
Váš model nyní bude mít v nabídce svého editoru položku 'Ověřit'.

Obrázek 3. Spuštění ověření platnosti z uživatelského rozhraní
Pokud model obsahuje neplatná data, ověření platnosti se nezdaří a zobrazí se dialogové okno podobné jako na obrázku 4.

Obrázek 4. Dialogové okno Problémy s ověřením platnosti
Při výběru jedné z diagnostik v dialogovém okně před klepnutím na tlačítko OK bude v editoru vybrán objekt, který způsobil porušení. Značkovače pro tyto diagnostiky budou zobrazeny rovněž v pohledu Problémy platformy Eclipse.
Chcete-li implementovat ověření platnosti jiným způsobem, například při uložení nebo otevření souboru, stačí, když provedete například toto:
public static boolean validateObject(EObject eObject)
{
Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObject);
return diagnostic.getSeverity() == Diagnostic.OK;
}
Při použití volby Diagnostician se výsledek vyhodnocení počítá na základě Diagnostic, nikoli pouze logického návratu. To vám umožňuje rozhodnout, která závažnost představuje selhání, a odkrýt informace o omezením a invariantech, které nebyly splněny. Pokud by vás například zajímaly pouze chyby a varování, mohli byste postupovat zhruba takto:
public static boolean validateObject(EObject eObject)
{
Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObject);
if (diagnostic.getSeverity() == Diagnostic.ERROR ||
diagnostic.getSeverity() == Diagnostic.WARNING)
{
System.err.println(diagnostic.getMessage());
for (Iterator i=diagnostic.getChildren().iterator(); i.hasNext();)
{
Diagnostic childDiagnostic = (Diagnostic)i.next();
switch (childDiagnostic.getSeverity())
{
case Diagnostic.ERROR:
case Diagnostic.WARNING:
System.err.println("\t" + childDiagnostic.getMessage());
}
}
return false;
}
return true;
}
Pamatujte, že při použití Diagnostician.INSTANCE.validate() skrytě získáte vnitřní ověření platnosti omezení Ecore díky validátoru EObjectValidator, který je základem pro všechny třídy validátorů generovaných balíků. To zahrnuje například: