Utolsó frissítés: 2005. június 23.
A dokumentum alapszintű áttekintést nyújt az EMF érvényesítési keretrendszeréről és néhány kódpéldával szolgál megvalósítás megkönnyítése érdekében. Az EMF összes szolgáltatásának teljesebb leírását az EMF: Eclipse Modeling Framework, Második kiadás (Addison-Wesley Professional, 2008) című kiadványban vagy maguknak a keretrendszer osztályoknak a Javadoc dokumentációjában találja.
Biztosítani akarja, hogy a modell adatai megfeleljenek a rájuk vonatkozó megszorításoknak? Ez az áttekintés bemutatja, hogy hogyan teheti ezt meg három gyors lépésben az EMF érvényesítési keretrendszerének használatával.
|
Állandó - Az adott modellhez meghatározott osztálymetódusként megvalósított. "Erősebb" utasítás az érvényességre vonatkozóan, mint egy megszorítás. Például: hasUSState() |
Nevesített megszorítás - Metódusként megvalósított egy külső érvényesítő osztályon, nem magán a modellen. "Gyengébb" utasítás az érvényességre vonatkozóan, mint egy állandó. Például: NonNegativeQuantity, ValidShipDate |
Séma alapú megszorítás - olyan, mint a nevesített megszorítás, de sémán belül meghatározva. Például: 'a quantity egy int kell legyen 0 és 100 között'. Mivel ezek a típusú megszorítások ismert viselkedésűek, nincs szükség további munkára a megvalósításukhoz: a kódelőállító automatikusan megvalósítja az összes egyszerű típus megszorítást.
<xsd:element name="quantity">
<xsd:simpleType>
<xsd:restriction base="xsd:int">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
|
| 1. lépés: | Megszorítások létrehozása a modellben |
| 2. lépés: | Megszorítások meghatározása |
| 3. lépés: | Előállítás és futtatás |
| Függelék: | Haladó témakörök |
Az összes EMF fejlesztéshez hasonlóan a kiindulási alap itt is lehet annotált Java, XML séma vagy Rose modell. A megszorítások meghatározásának módja a modell forrástól függ.
A Rose eszközben a műveletek <<inv>> sztereotípiája egy állandót képvisel. Példát a fenti 1. ábra tartalmaz.
Ha megszorítást akar felvenni a Rose 98 használatával, akkor nyissa meg a modellt, és válasszon ki egy osztályt (jelen példában az "Item"). Kattintson a jobb egérgombbal, majd válassza az előugró menü "Specifikáció megnyitása" menüpontját. Alternatív megoldásként kattintson duplán az "Item" elemre. Válassza az "Ecore" lapot, és kattintson a megszorítások mezőre a hozzáadásukhoz, mint ahogyan azt a fenti 2. ábra mutatja.
Sémának meghatározható <xsd:restriction/> (mint fent) vagy nevesített megszorítás:
<xsd:complexType name="Item">
<xsd:annotation>
<xsd:appinfo source="http://www.eclipse.org/emf/2002/Ecore"
ecore:key="constraints">
NonNegativeQuantity ValidShipDate
</xsd:appinfo>
</xsd:annotation>
...
</xsd:complexType>
Annotált Java esetén az alábbiak szerint határozhat meg állandókat és megszorításokat:
|
Állandó
/**
* @model
*/
public interface USAddress
{
...
/**
* @model
*/
boolean hasUSState(
DiagnosticChain diagnostics,
Map context);
...
}
|
Megszorítás
/**
* @model
annotation="http://www.eclipse.org/emf/2002/Ecore
constraints='NonNegativeQuantity ValidShipDate'"
*/
public interface Item
{
...
}
|
Importálja a modellt az EMF-be, majd állítson elő kódot az EMF modell előállítása ismertető 2-3. lépése szerint
Az előállított kód az alábbihoz hasonlóan néz ki:
|
Invariant, com.example.ppo.impl.USAddressImpl public boolean hasUSState(
DiagnosticChain diagnostics,
Map context)
{
// TODO: metódus megvalósítása
// -> az állandót sértő feltétel
// megadása
// -> a diagnosztika részleteinek ellenőrzése,
// beleértve a súlyosságot és az üzenetet
// Vagy távolítsa el a @generated elemet,
// vagy jelölje meg mint @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;
}
|
Constraint, com.example.ppo.util.PPOValidator public boolean validateItem_ValidShipDate(
Item item, DiagnosticChain diagnostics,
Map context)
{
// TODO: megszorítás megvalósítása
// -> a megszorítást sértő feltétel
// megadása
// -> a diagnosztikai részletek ellenőrzése
// beleértve a súlyosságot, kódot és üzenetet
// Mindenképpen távolítsa el a @generated
// annotációt vagy jelölje meg mint @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;
}
|
Az érvényesítőben (com.example.ppo.util.PPOValidator) is előállításra kerül minden egyes meghatározott állandó kódja, de ezek a metódusok egyszerűen csak megbízzák maguknak az objektumokban az állandó metódusait; például:
public boolean validateUSAddress_hasUSState(USAddress usAddress,
DiagnosticChain diagnostics, Map context)
{
return usAddress.hasUSState(diagnostics, context);
}
Mindkét esetben kézileg kell módosítani az előállított kódot, hogy elmagyarázza az EMF-nek az állandó vagy megszorítás megvalósításának módját. Az első esetben módosítsa az első sort erről:
if (false)
erre:
if ("US".equals(getCountry()) && getState() == null).
Amikor kész a megszorítások meghatározása, indítson egy új munkaterületet. Részleteket az EMF modell előállítása ismertető 4. lépése tartalmaz.
Most már lesz egy 'Érvényesítés' pont a modell szerkesztő menüjében.

3. ábra: Érvényesítés indítása a felhasználói felületről
Ha érvénytelen adatok vannak a modellben, akkor az érvényesítés hibát jelez a 4. ábrán látható párbeszédablakban.

4. ábra: Érvényesítési problémák párbeszédablak
Ha kijelöli valamelyik diagnosztikai üzenetet a párbeszédablakban, mielőtt az OK gombra kattintana, akkor a szerkesztőben ki lesz jelölve a sértést okozó objektum. A diagnosztikai üzenetek jelzői megjelennek az Eclipse Problémák nézetében is.
Ha más módon akarja megvalósítani az érvényesítést, például a fájlok mentésekor vagy megnyitásakor, akkor tegye az alábbihoz hasonlót:
public static boolean validateObject(EObject eObject)
{
Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObject);
return diagnostic.getSeverity() == Diagnostic.OK;
}
Diagnostician használatával a kiértékelés eredményét egy Diagnostic alapján számítja ki a rendszer, nem egyszerűen egy visszaadott logikai érték lesz. Így meghatározhatja, hogy milyen súlyossági szint jelent hibát, és exponálhatja a megszorítások és állandók azon információit, amelyek nem teljesültek. Ha például csak a hibák és a figyelmeztetések érdeklik, akkor tegye a következőket:
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;
}
A Diagnostician.INSTANCE.validate() alatt valamilyen belső Ecore megszorítás-érvényesítést kap az EObjectValidator osztálynak köszönhetően, ami az összes előállított csomag érvényesítő osztály alapja. Ezek a következők: