Wprowadzenie
Jednostki biznesowe są zarządzane w złożonych kontenerach w systemie. Kontenery te umożliwiają odczyt i zapis wszystkich danych encji. Dostęp do zapisu obejmuje również złożone operacje, takie jak dodawanie lub usuwanie nowych właściwości. Kontenery te określane są poniżej jako encje APP.
Encje APP mają szeroki interfejs z bogatym zakresem funkcji. Istnieje tylko kilka ograniczeń dostępu w celu ochrony niektórych funkcji lub danych przed użytkownikiem encji APP.
Hooki wymagają kontenerów danych do komunikacji z ich implementacją. Te kontenery danych powinny mieć tylko ograniczony interfejs:
- często dozwolony jest tylko dostęp do odczytu
- obliczone atrybuty są często dostępne tylko podczas zapisywania
Encje APP reprezentują przejściowy stan aplikacji, które mają zostać rozszerzone przez hooki i nie są odpowiednie dla hooków ze względu na szeroki interfejs.
Widoki obiektów reprezentują „widok” encji APP. Widoki obiektów są otoczką wokół części encji APP. Widok obiektu sam w sobie nie przechowuje żadnych danych. Ogólnie rzecz biorąc, każdy dostęp do odczytu i zapisu widoku obiektu jest obsługiwany przez powiązany obiekt biznesowy, chyba że w opisie widoku obiektu zdefiniowano specjalną obsługę.
Grupa docelowa
- Programiści
Opis
Każdy widok obiektu jest oparty na obiekcie biznesowym. Widok obiektu może zawierać atrybuty i relacje z tego obiektu biznesowego, a także wirtualne atrybuty i relacje.
W czasie wykonywania widok obiektu składa się z następujących komponentów:
- DataView – interfejs dostępu do odczytu danych widoku obiektu
- DataAccess – rozszerza interfejs DataView o dostęp do zapisu danych widoku obiektu. W przypadku DataAccess rozróżnia się dostęp Ograniczony i Nieograniczony. Dostęp Ograniczony umożliwia dostęp do właściwości widoku obiektu, które zostały dodane przez rozszerzenia obiektów biznesowych lub rozszerzenia widoku obiektu w tym samym systemie programowania.
- DataObject – zapewnia dostęp do obiektu biznesowego encji APP dla DataView i DataAccess.
DataView i DataAccess tworzą interfejs dostępu do obiektu biznesowego w encji APP. Dostęp do atrybutów i relacji jest realizowany przez obiekt biznesowy, jeśli to możliwe. Logika ta musi być zakodowana w DataObject tylko wtedy, gdy różni się od obiektu biznesowego.
Widok obiektu można utworzyć tylko w tym samym systemie programowania, co przypisany obiekt biznesowy.
Widok obiektu może zostać uzupełniony o nowe atrybuty i relacje w dalszych systemach programowania lub systemach programowania aplikacji z rozszerzeniem widoku obiektu.
Widoki obiektów
Opis widoku obiektu jest zapisywany jako obiekt deweloperski XML. Struktura pliku XML została przedstawiona na poniższym przykładzie. Tabelaryczny opis elementów użytych w tym przykładzie można znaleźć w kolejnych rozdziałach.
<?xml version=”1.0″ encoding=”utf-8″?> <dataview xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”DataView.xsd”> <object> com.cisag.app.general.obj.Item </object> <implementation> com.cisag.app.general.item.log.ItemObject </implementation> <javadoc> Widok obiektu dla obiektu biznesowego Item w aplikacji Artykuły. Widok obiektu jest zmienny tylko dla podstawowego widoku artykułu. W widokach specyficznych dla obszarów używany jest wyłącznie niemodyfikowalny DataView. </javadoc> <viewinterface> com.cisag.app.general.model.MasterDataView </viewinterface> <viewinterfacesuffix> com.cisag.app.general.model.ItemView </viewinterfacesuffix> <!-- Atrybut "guid" nie może zostać zmieniony i --> <!-- powinien mieć inną etykietę i dokument Java. --> <attribute property="READ_ONLY"> <name>guid</name> <datatype> com.cisag.app.general.model.ItemViewGuid </datatype> <javadoc> Atrybut "guid" jest częścią klucza głównego pliku Item. Ten identyfikator jest częścią klucza głównego danych specyficznych dla frameworka danych elementu. </javadoc> </atrybut> <!-- Relacja ProductionItems nie powinna być wyświetlana -->. <!-- powinna być wyświetlana. --> <relation property="EXCLUDED"> <name>ProductionItems</name> </relation> <!-- Relacja DefaultVariantItem powinna być ustawiona na --> <!-- widok obiektu tylko do odczytu elementu. --> <relation property="READ_ONLY"> <name>DefaultVariantItem</name> <targetview> com.cisag.app.general.model.Item </targetview> </relation> <!-- Wirtualna relacja 1:n dla alternatywy --> <!-- Artykuł. -> <virtualrelation property="READ_ONLY" cardinality="ONE_MANY"> <name>AlternativeItems</name> <targetview> com.cisag.app.general.model.AlternativeItem </targetview> </virtualrelation> </dataview>
Definicja widoku obiektu
Widok obiektu jest opisany przez dokładnie jeden element dataview. Element ten zawiera kolejne elementy. Są one podzielone na następujące grupy:
- dane dotyczące widoku obiektu i jego interfejsów
- dane dotyczące atrybutów widoku obiektu
- dane dotyczące relacji widoku obiektu
Element | Opis |
object | Pełna nazwa obiektu biznesowego wraz z przestrzenią nazw. Każdy widok obiektu należy dokładnie do jednego obiektu biznesowego. Ten element jest obowiązkowy. |
implementation | Pełna nazwa klasy obiektu danych dla widoku obiektu wraz z przestrzenią nazw. Podana klasa musi być pochodną klasy DataObject. Ten element jest obowiązkowy. |
javadoc | JavaDoc do komentarza klasy dla DataView powiązanego z widokiem obiektu. JavaDoc musi opisywać zadania oraz, w razie potrzeby, ograniczenia widoku obiektu. |
viewinterface | Nazwa interfejsu Java, który rozszerza DataView. Opcjonalny interfejs widoku (View Interface) może rozszerzać DataView o dodatkowe metody lub umożliwiać dostęp do atrybutów i relacji niezależnie od DataView.Więcej informacji znajduje się w rozdziale Rozszerzenie poprzez interfejsy widoku/dostępu. |
viewinterfacesuffix | Jeśli interfejs widoku (View Interface) jest generyczny, można podać sufiks w celu określenia parametrów generycznych interfejsu.Nie trzeba podawać zewnętrznych znaków „<” i „>”. Jeśli w parametrze generycznym jest potrzeba „<” i „>”, należy je zakodować zgodnie ze standardem XML.Zamiast „<A,B>” należy podać „A,B”, a zamiast „<C>” podać „C<D>”. |
accessinterface | Nazwa interfejsu Java, który rozszerza DataAccess. Opcjonalny interfejs dostępu (Access Interface) jest traktowany analogicznie do interfejsu widoku (View Interface).Więcej informacji znajduje się w rozdziale Rozszerzenie poprzez interfejsy widoku/dostępu. |
accessinterfacesuffix | Jeśli interfejs dostępu (Access Interface) jest generyczny, można podać sufiks w celu określenia parametrów generycznych interfejsu.Nie trzeba podawać zewnętrznych znaków „<” i „>”. Jeśli w parametrze generycznym jest potrzeba „<” i „>”, należy je zakodować zgodnie ze standardem XML.Zamiast „<A,B>” należy podać „A,B”, a zamiast „<C>” podać „C<D>”. |
Definicja atrybutów
Widoki obiektów zawierają wybrane atrybuty bazowego obiektu biznesowego oraz opcjonalnie, również wirtualne, czyli obliczane, atrybuty:
- za pomocą elementu attribute można zmienić właściwości atrybutu obiektu biznesowego. Można m.in. ograniczyć dostęp do atrybutu obiektu biznesowego do odczytu lub zapisu.
- za pomocą elementu virtualattribute można utworzyć obliczany atrybut. Wirtualne atrybuty muszą być zaimplementowane w DataObject i nie obsługują tablic ani złożonych atrybutów (Parts), z wyjątkiem specjalnych Parts, np. dla walut krajowych.
Dalsze informacje na temat implementacji wirtualnych atrybutów znajdują się w sekcji Atrybuty wirtualne w DataObject.
Dla każdego atrybutu możliwego do odczytu zostanie wygenerowana metoda getter w DataView, a dla każdego atrybutu możliwego do zapisu zostanie wygenerowana metoda setter w DataAccess.
Poniższa tabela objaśnia elementy i atrybuty dozwolone w atrybutach obiektów biznesowych oraz wirtualnych atrybutach.
Element | Opis |
name | Ścieżka atrybutu kolumny. W przypadku atrybutu obiektu biznesowego musi istnieć kolumna o podanej ścieżce atrybutu. Ścieżka atrybutu jest złożona, jeśli zawiera kropki „.” lub nawiasy „[]”. Dla złożonych ścieżek atrybutów nie są generowane metody w DataView ani DataAccess. Nazwa wirtualnego atrybutu musi jednoznacznie identyfikować atrybut. Np. nie może istnieć wiele atrybutów obiektu biznesowego o tej samej nazwie.Wirtualne atrybuty nie mogą być złożone. W rozszerzeniach widoków obiektów nazwa musi zaczynać się od prefiksu deweloperskiego rozszerzenia widoku obiektu, rozpoczynającego się małą literą i podkreśleniem „_”.W rozszerzeniach widoków obiektów w aplikacjach po tej nazwie następuje dodatkowo nazwa aplikacji pisana małymi literami oraz kolejne podkreślenie. |
property |
Atrybut property jest określany w elemencie attribute lub virtualattribute. Zarządza on widocznością i dostępem do atrybutu obiektu biznesowego lub wirtualnego:
|
datatype | Pełna nazwa logicznego typu danych. Jeśli typ danych jest powiązany z Data-Description, zostanie ona użyta w przypadku wyświetlania atrybutu w DataView. W przypadku atrybutów obiektów biznesowych typ danych jest opcjonalny i zastępuje typ danych zapisany w atrybucie. Typ pierwotny musi w tym przypadku odpowiadać pierwotnemu typowi atrybutu. Dla wirtualnych atrybutów wymagane jest podanie typu danych, aby w pełni zdefiniować wirtualny atrybut. |
javadoc | Opcjonalny JavaDoc do opisu atrybutu. Jest on zapisywany zarówno w getterze w DataView, jak i w setterze w DataAccess. Złożone atrybuty nie mają JavaDoc. |
targetObject | Pełna nazwa obiektu docelowego. Jeśli atrybut ma przypisany obiekt docelowy, to ten atrybut zawiera klucz obcy do obiektu docelowego. Klucz główny obiektu docelowego może składać się tylko z jednego atrybutu. Typy danych obu atrybutów muszą być identyczne. Obiekt docelowy jest używany na przykład do wyboru odpowiedniego Entity-Field. |
Atrybuty niewirtualne mogą być zapisane jako wartości domyślne, z wyjątkami opisanymi poniżej.
Następujące atrybuty są tylko do odczytu (READ_ONLY):
- atrybuty klucza głównego
- atrybuty klucza biznesowego
- validFrom
- validUntil
- updateInfo
- timeZoneGuid
- _organisation
- _currencyCombo
- _conversionDate
- _clob
Następujący atrybut jest domyślnie ukryty (EXCLUDED):
- managingSystem
Definicja relacji
- za pomocą elementu relation można zmienić właściwości relacji obiektu biznesowego. Można użyć odpowiedniego widoku obiektu jako celu relacji zamiast obiektu biznesowego.
- za pomocą elementu virtualrelation można utworzyć obliczaną relację.
Warunki generowania metody:
- jeśli cel relacji nie jest zmienny, metoda jest tworzona wyłącznie w DataView.
- jeśli celem relacji jest widok obiektu, metoda zwraca ograniczenie dostępu do obiektu źródłowego:
- w DataView zwraca DataView
- w DataAccess zwraca DataAccess
- w DataAccess.Full zwraca DataAccess.Full
Szczegóły dotyczące implementacji relacji znajdują się w rozdziale Relacje w DataObject.
Element | Opis |
name | Unikalna nazwa relacji. W przypadku relacji obiektu biznesowego musi istnieć relacja o danej nazwie. Wirtualne relacje mogą nadpisywać właściwości relacji obiektu biznesowego. W rozszerzeniach widoków obiektów nazwa musi zaczynać się od prefiksu deweloperskiego rozpoczynającego się wielką literą i podkreśleniem „_”. W aplikacjach dodaje się nazwę aplikacji i kolejne podkreślenie. |
property | Atrybut property jest określany w elemencie relation lub virtualrelation. Steruje on widocznością relacji oraz dostępem do celu relacji:EXCLUDED – relacja jest zawarta w obiekcie biznesowym, ale nie jest widoczna w widoku obiektu. Wirtualnych relacji nie można ukrywać.PERSISTENT – relacja jest zawarta w obiekcie biznesowym i powinna być weryfkowana przez persistence service. Dla tej relacji w DataObject nie ma metody retrieve. Wirtualne relacje nie mogą być obliczane przez persistence service. Jeśli celem relacji jest widok obiektu, DataObject widoku musi posiadać konstruktor z obiektem biznesowym jako jedynym parametrem.Więcej informacji można znaleźć w rozdziale Właściwość PERSISTENT.
READ_ONLY – cel relacji jest obliczany za pomocą DataObject. Cel relacji to obiekt biznesowy lub widok obiektu. W DataAccess widoku obiektu nie ma metody retrieve…Access, więc cel relacji nie jest modyfikowalny. Więcej informacji można znaleźć w rozdziale Właściwość READ_ONLY. MUTABLE – cel relacji jest modyfikowalny i obliczany przez DataObject. Cel relacji musi być widokiem obiektu. Więcej informacji można znaleźć w rozdziale Właściwość MUTABLE. |
cardinality | Atrybut cardinality jest określany w elemencie virtualrelation. Wskazuje model relacji wirtualnej:ONE_ONE – relacja wskazuje na maksymalnie jeden obiekt docelowy.ONE_MANY – relacja wskazuje na dowolną liczbę obiektów docelowych.Więcej informacji na temat relacji 0…n można znaleźć w rozdziale One-Many dla relacji 0…n. |
targetobject | Jeśli celem relacji jest obiekt biznesowy, można określić pełną nazwę docelowego obiektu biznesowego. |
targetview | Jeśli celem relacji jest widok obiektu, można określić pełną nazwę docelowego widoku obiektu. Jeśli widok obiektu, w którym zapytanie o relację jest wykonywane, ma ograniczony dostęp, wszystkie docelowe widoki obiektów również będą miały ograniczony dostęp.W rozdziale Ograniczony dostęp można znaleźć szczegółowe informacje. |
javadoc | Opcjonalny JavaDoc do opisu relacji. JavaDoc jest zapisywany zarówno w metodzie zapytania DataView, jak i DataAccess. |
Rozszerzenie poprzez interfejsy widoku/dostępu
Klasy View i Access mogą rozszerzać dowolne interfejsy. Metody interfejsów mogą zawierać metody dostępu do atrybutów i relacji, jak również nowe metody bez odniesienia do atrybutu lub relacji.
Dostęp do atrybutów i relacji
Kilka widoków obiektu dla obiektu biznesowego może reprezentować różne zastosowania obiektu biznesowego.
Interfejsy Java wszystkich widoków obiektów dla obiektu biznesowego nie mają wspólnego interfejsu. Jednak ważne metody (dostęp do atrybutów i relacji) są wspólne dla wszystkich zastosowań. Te wspólne metody można podsumować w widoku i/lub interfejsie dostępu. Interfejsy Java widoków obiektów mogą rozszerzać te interfejsy widoku i dostępu. Algorytmy mogą zatem uzyskiwać dostęp do różnych widoków obiektów za pośrednictwem wspólnego super interfejsu.
String getCity() void setCity(String newValue) String getPostalCode() void setPostalCode(String newValue)
Metody get
są zawarte w interfejsie Java AbstractAddressView
, a metody set
w interfejsie Java AbstractAddressAccess
. AbstractAddressAccess
rozszerza AbstractAddressView
.
Pole do wyświetlania miasta i kodu pocztowego powinno używać interfejsów Java AbstractAddressView i/lub AbstractAddressAccess zamiast konkretnego widoku obiektu.
Nowe metody
Interfejs widoku lub dostępu może zawierać metody, które nie realizują ani dostępu do atrybutu, ani do relacji. Takie metody są wywoływane z tą samą sygnaturą na DataObject.
void xyz()
DataObject należący do widoku obiektu musi zawierać metodę void xyz().
Jeśli metoda xyz() zostanie wywołana na widoku obiektu, odpowiednia metoda zostanie wywołana na DataObject.
Metadane nie zawierają żadnych informacji o metodach widoku i interfejsach dostępu. Nie można zatem uzyskać dostępu do metod za pośrednictwem metadanych (ścieżki).
Te nowe metody mogą być używane do wywoływania dowolnych złożonych funkcji za pośrednictwem DataObject na encji APP.
Ograniczony dostęp
Obiekty biznesowe mogą być rozszerzane o nowe atrybuty za pomocą rozszerzeń obiektów biznesowych, m.in. w ramach dostosowywania klienta lub w systemie tworzenia aplikacji.
W interfejsie aplikacji aplikacja często może zmieniać tylko te atrybuty, które sama utworzyła. Ograniczony dostęp zapewnia, że można zmienić tylko atrybuty rozszerzeń obiektów biznesowych, które zostały utworzone w powiązanym systemie tworzenia aplikacji. Wszystkie inne atrybuty w obiekcie biznesowym nie mogą i nie mogą być zmieniane.
Podczas korzystania z widoku danych z ograniczonym dostępem (DataAccess) w hooku lub w rozszerzeniu widoku danych, liczba dostępnych setterów jest ograniczona do atrybutów odpowiednich dla przestrzeni nazw deweloperskiej użytkownika. Wywołanie settera niemodyfikowalnego atrybutu prowadzi do błędu runtime z DataAccess.
DataAccess widoku obiektu zapewnia settery dla wszystkich atrybutów, które zostały dodane przez rozszerzenie obiektu biznesowego. Setery dla atrybutów obiektu biznesowego są zawarte w wewnętrznym interfejsie Full, który dziedziczy po DataAccess. Należy go użyć, aby utworzyć widok obiektu z pełnym dostępem.
Tworzenie widoku obiektu dla elementu z ograniczonym dostępem:
ItemAccess restrictedAccess = dvm.create( ItemAccess.class, itemDataObject);
Po utworzeniu widoku elementu z ograniczonym dostępem można zmienić wszystkie atrybuty wszystkich rozszerzeń obiektów biznesowych. Zmienne atrybuty są dalej ograniczane, gdy DataAccess jest używany w hooku lub gdy widok obiektu jest rozszerzany.
Utworzenie widoku obiektu dla elementu z pełnym dostępem:
ItemAccess.Full fullAccess = dvm.create( ItemAccess.Full.class, itemDataObject);
Po utworzeniu widoku elementu z pełnym dostępem wszystkie atrybuty można zmieniać bez ograniczeń.
Implementacja obiektu DataObject
DataView reprezentuje zewnętrzny interfejs obiektu biznesowego w encji APP.
Infrastruktura DataView przekazuje wywołania metod z DataView do bazowego obiektu biznesowego. Niektóre metody, takie jak dostęp do wirtualnych atrybutów lub relacji, nie mogą zostać odebrane przez infrastrukturę. Wszystkie metody DataView, które nie zostały zdefiniowane przez infrastrukturę, muszą zostać zaimplementowane w obiekcie DataObject.
DataObject mapuje dostęp do DataView lub DataAccess na encję APP. Sam obiekt DataObject jest tylko pośrednikiem. Niektóre instancje obiektu DataObject są generowane podczas dostępu do DataView. Może istnieć kilka obiektów DataObject dla obiektu biznesowego w encji APP w dowolnym momencie. Instancje DataObject są często przebudowywane i odrzucane.
Implementacja obiektu DataObject musi spełniać następujące warunki:
- powiązany obiekt biznesowy jest znany w momencie wywołania konstruktora
- DataObject nie powinien wykonywać żadnych złożonych obliczeń w konstruktorze
- DataObject nie może przechowywać własnego stanu
Podczas definiowania widoku obiektu określana jest klasa powiązanego obiektu DataObject. Instancja powiązanego obiektu DataObject jest wymagana do utworzenia widoku DataView lub dostępu DataAccess.
Sekwencja wywołań metod pobierania, getterów i setterów nie jest ustalona podczas przesyłania danych z i do interfejsu (dataFromUI i dataToUI). Metody atrybutów wirtualnych i relacji nie mogą zmieniać innych atrybutów, które mogą być zmieniane w interfejsie użytkownika.
Jednym z rozwiązań byłoby uczynienie atrybutu a niezmiennym lub niewidocznym. Oznacza to, że nie może być konfliktu z przeniesieniem a i v z interfejsu, ponieważ a nie jest przenoszone z interfejsu.
Ten sam problem występuje również, gdy na przykład setter atrybutu wirtualnego zmienia obiekt docelowy relacji z atrybutami zmiennymi.
Relacje bez zmiennych atrybutów i atrybuty niezmienne mogą być zmieniane przez settery, o ile sekwencja wywołań nie jest istotna.
Atrybuty wirtualne w DataObject
Getter i setter atrybutów wirtualnych muszą być zaimplementowane w DataObject z takimi samymi sygnaturami jak w DataView lub DataAccess.
Należy również pamiętać, że nie można wpływać na żadne inne zmienne atrybuty za pomocą ustawiaczy atrybutów wirtualnych.
class ItemObject extends DataObject<Item> { ... public boolean isDollar() { return getObject().getDescription().endsWith("$"); } ... }
Cechy szczególne
Jeśli atrybut wirtualny X ma część P jako typ danych, przynajmniej metody PMutable getMutableX() i setX(PMutable v) muszą być zaimplementowane w DataObject. Metoda P getX() nie musi być zaimplementowana. Jeśli getX() nie została zaimplementowana, getMutableX() jest wywoływana zamiast getX(), gdy getX() jest wywoływana w widoku obiektu w DataObject. Wynik funkcji getMutableX() jest konwertowany na część niezmienną.
Relacje w DataObject
Widok obiektu może wyrażać relacje między obiektami biznesowymi lub widokami obiektów. Widok obiektu często reprezentuje część encji APP. Encja APP zarządza zestawem przejściowych obiektów biznesowych. Relacje między obiektami biznesowymi w ramach encji APP mogą być analizowane tylko przez samą encję APP. Relacje z obiektami biznesowymi, które nie są zarządzane przez encje APP, są obliczane przy użyciu persistence service. Jeśli infrastruktura widoków obiektów nie może ogólnie obliczyć relacji, relacja musi zostać zaimplementowana w DataObject.
Relacje 0…n mogą zwracać dowolną liczbę instancji obiektów docelowych. Obiekty docelowe są obliczane w zależności od relacji w DataObject lub w infrastrukturze widoków obiektów.
Zawartość relacji 0…n jest zwracana przez widok obiektu jako obiekt typu one-many. Zawiera on przejściowe instancje obiektów docelowych, albo klucze do ładowania obiektów docelowych z persistence service. Zestaw kluczy musi zostać zdefiniowany podczas tworzenia obiektu one-many. Po utworzeniu obiektu klucze nie mogą już ulec zmianie. Obiekty docelowe są ładowane tylko wtedy, gdy są dostępne, w zależności od obiektu one-many.
Przynajmniej klucz jest przechowywany w pamięci głównej dla każdego obiektu docelowego w obiekcie typu one-many. Podczas projektowania widoku obiektu należy pamiętać, że wszystkie relacje 0…n mają dużą, ale ograniczoną liczbę obiektów docelowych.
Należy pamiętać, że obiekty docelowe obiektu one-many mogą mieć wartość „zero”.
Obiekt one-many umożliwia losowy dostęp do obiektów docelowych. Obiekt one-many jest używany przez użytkownika widoku obiektu do werbalizowania, czy obiekty docelowe są obliczane przejściowo w encji APP, czy za pośrednictwem persistence service.
Różne implementacje interfejsu one-many sprawiają, że jest on łatwiejszy w użyciu:
- llasa OneManyBase jest klasą bazową dla niestandardowych implementacji interfejsu OneMany
- llasa OneManyObjectIterator implementuje obiekt one-many na wynikach ObjectIterator
- llasa OneManyCollection implementuje obiekt one-many na kolekcji CisObject
Jeśli wynikiem klas one-many jest widok obiektu, powyższe klasy one-many można utworzyć dla DataObject lub BusinessObject widoku obiektu. Jeśli DataObject należący do widoku obiektu ma tylko obiekt biznesowy jako parametr w konstruktorze, nie jest wymagana żadna specjalna implementacja. Jeśli konstruktor obiektu DataObject ma więcej lub inne parametry, konstruktor ten musi zostać wywołany w implementacji wewnętrznego interfejsu OneManyBase.DataObjectBuilder.
Więcej informacji na temat implementacji widoków obiektów można znaleźć w dokumentacji Java klasy com.cisag.pgm.base.OneMany.
public OneMany<AlternativeItemObject> retrieveAlternativeItems() { CisObjectIterator iter = om.getObjectIterator( "SELECT FROM com.cisag.app.general.obj.Item o "+ "WHERE o:alternativeItem=?"); iter.setGuid(1,getObject().getGuid()); return new OneManyCisObjectIterator(iter, new OneManyBase.DataObjectBuilder<Item> { DataObject build(Item item) { return new AlternativeItemObject(entity,item); } }); }
Jeśli cel relacji z DataAccess może zostać zmieniony (właściwość MUTABLE), wówczas relacja ta musi zostać zaimplementowana w DataObject. W tym przypadku encji APP generalnie zarządza zmienną i przejściową instancją obiektu biznesowego.
Należy zaimplementować następującą metodę pobierania dla zmiennej relacji o nazwie {RelationName} i obiektu biznesowego {BusinessObject}:
0:1 Relacja
DataObject<{BusinessObject}> retrieve{RelationName}()
0:n Relacja
OneMany<DataObject<{BusinesObject}>> retrieve{Relationname}()
Jeśli DataAccess ma ograniczony dostęp, wszystkie obiekty docelowe z ograniczonym dostępem są również tworzone podczas zapytania o relację. W widoku obiektu docelowego (element targetview) można określić dla relacji, że widok obiektu docelowego nie powinien mieć ograniczonego dostępu, niezależnie od widoku obiektu źródłowego.
public ItemObject retrieveDefaultVariantItem() { return new ItemObject(entity, entity.getDefaultVariantItem()); }
Jeśli celem relacji jest widok obiektu, który nie może zostać zmieniony (właściwość READ_ONLY) i nie można go określić za pomocą mapowania obiektów biznesowych obiektu źródłowego, relacja musi zostać zaimplementowana w obiekcie DataObject. Dzieje się tak na przykład wtedy, gdy relacja jest tak złożona, że nie można jej wyrazić w metadanych obiektu biznesowego.
Implementacja w DataObject jest analogiczna do relacji z właściwością MUTABLE.
Nie może istnieć implementacja w obiekcie DataObject dla relacji, które mają być oceniane za pomocą mappera obiektów biznesowych (właściwość PERSISTENT). Jeśli widok obiektu został określony jako cel dla tych relacji (element „targetview”), musi być możliwe utworzenie tego widoku obiektu tylko z obiektem biznesowym. W takim przypadku DataObject docelowego widoku obiektu musi mieć konstruktor z powiązanym obiektem biznesowym jako jedynym parametrem. Jeśli taki konstruktor nie istnieje, podczas odpytywania relacji wystąpi błąd wykonania.
SalesOrderTypeObject(SalesOrderType soType)
Atrybuty przetłumaczalne (NLS)
Atrybuty przetłumaczalne (NLS) są traktowane inaczej niż zwykłe ciągi znaków w widokach obiektów. Dane atrybutu przetłumaczalnego są zwykle zarządzane przez encję APP w klasie NLSData. Należy utworzyć getter z przyrostkiem „$NLS”, aby uzyskać dostęp do NLSData w encji APP.
public NLSData getDescription$NLS() { return ...; }
Alternatywnie do powyższego mechanizmu, NLSData mogą być również dostarczane z interfejsem DataObject.GenericNLS.
public NLSData getNLSData(String attributePath) { return entity.getNLSData(attributePath); }
Niezależnie od interfejsu DataObject.GenericNLS, NLSData jest określana za pomocą tej metody, jeśli istnieje metoda $NLS.
Generowanie klas Java
DataView i DataAccess są generowane dla każdego widoku obiektu za pomocą narzędzia crtdv. Polecenie toolshell ma zwykłe parametry programistyczne -j dla zadania deweloperskiego i -o dla obiektu deweloperskiego.
Jeśli widok obiektu ma zostać usunięty z zadania deweloperskiego, konieczne jest ustawienie polecenia tollshell crtdv z parametrem -resetState.
Gdy generowany jest bazowy obiekt biznesowy (przy użyciu crtbo), generowane są również klasy Java dla widoku obiektu. Jeśli DataView został automatycznie dołączony do zadania deweloperskiego podczas generowania rozszerzenia obiektu biznesowego, DataView jest automatycznie usuwany w rmvbo.
CisDataViewManager
CisDataViewManager może być używany do generowania widoków obiektów i odpytywania metadanych widoków obiektów. CisDataViewManager jest odpytywany przez CisEnvironment.
Tworzenie widoków obiektów
Widok obiektu można utworzyć za pomocą żądanego interfejsu DataView lub DataAccess i pasującego obiektu DataObject.
<O extends CisObject, V extends DataView<O>, D extends DataObject<O>> V create(Class<V> dataClass, D dataObject)
Jeśli obiekt DataObject ma konstruktor, którego jedynym parametrem jest obiekt biznesowy, DataViewManager może użyć obiektu biznesowego do utworzenia odpowiedniego obiektu DataObject. W takim przypadku można również użyć następującej metody:
<O extends CisObject, V extends DataView<O>> V create(Class<V> dataClass, O object)
Interfejs, dla którego ma zostać utworzony widok obiektu, jest określony w parametrze dataClass
.
ItemView view = dvm.create(ItemView.class, dataObject);
Tworzenie widoku obiektu z ograniczeniami:
ItemAccess access = dvm.create(ItemAccess. class, dataObject);
Tworzenie modyfikowalnego widoku obiektu:
ItemAccess.Full access = dvm.create(ItemAccess.Full.class, dataObject);
Zapytanie o metadane widoków obiektów
Metadane widoku obiektu mogą być odpytywane w DataViewManager. Metadane są wymagane do ogólnego dostępu do widoków obiektów. W rozdziale Ścieżki znajdują się szczegółowe informacje dotyczące dostępów.
Zapytanie o metadane widoku obiektu można wykonać przy użyciu następującej metody
<O extends CisObject, V extends DataView<O>> CisDataViewMetaData getMetaData(Class<V> dataClass);
Aby uzyskać ogólny dostęp do obiektów biznesowych, metadane widoku obiektu można również określić dla obiektu biznesowego za pomocą następujących metod:
<O extends CisObject> CisDataViewMetaData getObjectMetaData( Class<O> businessObjectClass); CisDataViewMetaData getObjectMetaData(byte[] classGuid);
Kopiowanie atrybutów
CisDataViewManager oferuje dwie pomocnicze procedury, za pomocą których atrybuty DataView mogą być kopiowane do DataAccess. Metody te mogą być wywoływane tylko z DataView i DataAccess tego samego widoku obiektu. Dostępna jest metoda kopiowania wszystkich atrybutów. Ponadto można kopiować tylko wybrane atrybuty. Metody są następujące
copyTo( DataView<?> sourceView, DataFullAccess<?> targetFullAccess); copyTo( DataView<?> sourceView, DataFullAccess<?> targetFullAccess, AttributeFilter attributeFilter);
Ścieżki
Ścieżka ogólnie definiuje dostęp, zaczynając od widoku obiektu A, do atrybutu A lub innego widoku obiektu, który można osiągnąć z A za pośrednictwem łańcucha relacji 0…1. Ścieżki spełniają następujące zadania:
- pole w aplikacji interaktywnej jest powiązane ze ścieżką:
- komunikaty o błędach mogą być powiązane z powiązanymi polami poprzez ścieżkę (czerwone narożniki)
- dane są automatycznie wymieniane między widokiem obiektu a polem w aplikacji interaktywnej za pośrednictwem ścieżki.
- ogólny dostęp do danych widoku obiektu jest możliwy przy użyciu metadanych widoku obiektu i ścieżki.
Ścieżki muszą być tworzone w programie aplikacji, np. w celu wysłania wiadomości. Aby mogła ona zostać utworzona w możliwie najbezpieczniejszy sposób, identyfikatory relacji i kolumn są generowane jako enum w DataView.
Ścieżki mogą być wyszukiwane w klasie com.cisag.pgm.base.Path
przy użyciu między innymi następującej metody:
Path getInstance(Enum<?>... attributeOrRelation)
Klasa Path
ma dalsze metody generowania ścieżek z metadanych widoku obiektu lub z ciągu znaków. Metody te są opisane w JavaDoc klasy.
public interface ItemView { public static enum Attribute { $guid, $number, ... } public static enum Relation { $DefaultVariantItem, $AlternativeItems, ... } }
Ścieżki mogą być tworzone za pomocą enum w DataView
:
Path numberPath = Path.getInstance(ItemView.Attribute.$number); Path variantGuidPath = Path.getInstance( ItemView.Relation.$DefaultVariantItem, ItemView.Attribute.$number);
Ścieżki mogą być używane w Menedżerze wiadomości do wysyłania wiadomości w celu przypisania wiadomości do jednego lub więcej pól:
mm.setProgramMessageDataViewPaths(numberPath); mm.sendMessage("XYZ",4711, "abc");
Można użyć ścieżki do ogólnego dostępu do danych widoku obiektu:
DataView view = .... String number = (String)view.getValue(numberPath); DataFullAccess fullAccess = .... fullAccess.setValue(variantGuidPath, variantGuid);
Dokument Java klas com.cisag.pgm.base.DataView, com.cisag.pgm.base.DataAccess i com.cisag.pgm.base.DataFullAccess zawiera pełny opis wszystkich metod ogólnego dostępu do danych widoku obiektu.
Rozszerzenie widoku obiektu
System Comarch ERP Enterprise można rozszerzyć o nowe funkcje w systemach deweloperskich niższego szczebla lub systemach tworzenia aplikacji. W tym celu konieczne są również zmiany w modelu danych. Encje APP ze standardu muszą uwzględniać model danych rozszerzony o nowe funkcje. Odpowiednie definicje Hook Contract i interfejsy są dostarczane w celu rozszerzenia encji APP.
Jeśli nowe atrybuty i relacje zostaną dodane do obiektu biznesowego w encji APP z rozszerzeniem obiektu biznesowego, wszystkie te atrybuty i relacje zostaną automatycznie uwzględnione w powiązanych widokach obiektów.
Jeśli właściwości nowych atrybutów mają zostać zmienione lub encja APP zostanie rozszerzona o nowe podmioty zależne, na przykład wymagane są dodatkowe metadane dla tego rozszerzenia. To rozszerzenie jest określane jako rozszerzenie warstwy obiektu.
Rozszerzenie warstwy obiektów składa się z metadanych atrybutów i metadanych relacji. Nazwy atrybutów i relacji muszą być zgodne z konwencją nazewnictwa pochodzącą z przestrzeni nazw rozwoju rozszerzenia warstwy obiektów.
Wszystkie relacje w rozszerzeniu warstwy obiektów com.xyz.app.general.model.ItemView muszą zaczynać się od przedrostka „Xyz_”.
W pewnych przypadkach w systemie tworzenia aplikacji można opracować kilka aplikacji. Rozszerzenie warstwy obiektów może zmieniać tylko atrybuty i relacje z tej samej aplikacji. Nazwy wirtualnych atrybutów i relacji muszą być unikalne we wszystkich aplikacjach opracowanych w tym systemie.
Opis rozszerzenia warstwy obiektów jest rejestrowany jako obiekt programistyczny XML. Struktura XML jest wprowadzana na poniższym przykładzie. Tabelaryczny opis elementów użytych w tym przykładzie można znaleźć w kolejnych sekcjach. Elementy atrybutów i relacji zostały już opisane w widoku obiektu.
com.xyz.app.general.model.Item<?xml version="1.0" encoding="utf-8"?> <dataviewextension xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="DataView.xsd"> <dataview> com.cisag.app.general.item.model.Item </dataview> <implementation> com.xyz.app.general.log.ItemExtension </implementation> <virtualattribute property="READ_ONLY"> <name>xyz_derivedState</name> <datatype> com.xyz.app.general.model.ItemDerivedState </datatype> <javadoc> Stan pochodny jest obliczany na podstawie stanu elementu. </javadoc> </virtualattribute> <!-- Relacja Xyz_TopSalesOrders nie powinna być wyświetlana --> <!– nie będzie wyświetlana. –> <relation property="EXCLUDED"> <name>Xyz_TopSalesOrders</name> </relation> <!-- Relacja Xyz_ItemFashionExtension wskazuje na -->. <!-- Zależny w encji APP elementu. --> <relation property="MUTABLE"> <name>Xyz_ItemFashionExtension</name> <targetview> com.xyz.app.general.model.ItemFashionExtension </targetview> <javadoc> Wszystkie rozszerzenia dla rozwiązania Fashion są implementowane poprzez tę relację. </javadoc> </relation>. </dataviewextension>
Definicja rozszerzenia warstwy obiektów
Rozszerzenie warstwy obiektów jest opisane przez dokładnie jeden element dataviewextension
. Element ten zawiera dalsze elementy. Są one podzielone na następujące grupy:
- dane dotyczące rozszerzenia warstwy obiektów
- dane dotyczące atrybutów rozszerzenia warstwy obiektów
- dane dotyczące relacji rozszerzenia warstwy obiektów
Poniższa tabela wyjaśnia wszystkie elementy opisujące dane rozszerzenia warstwy obiektów:
Element | Opis |
---|---|
dataview | Pełna nazwa widoku obiektu wraz z przestrzenią nazw. Ten element jest obowiązkowy. |
implementation | Pełna nazwa klasy DataExtension dla rozszerzenia widoku obiektu wraz z przestrzenią nazw. Podana klasa musi być pochodną klasy DataExtension . Ten element jest obowiązkowy. |
Definicja atrybutów i relacji w rozszerzeniu warstwy obiektów jest identyczna z definicją w widokach obiektów. Nazwy wszystkich atrybutów i relacji muszą zaczynać się od prefiksu deweloperskiego rozszerzenia warstwy obiektów, analogicznie do rozszerzeń obiektów biznesowych.
Więcej informacji można znaleźć w rozdziałach Definicja atrybutów i Definicja relacji.
Implementacja rozszerzenia DataExtension
Rozszerzenie DataExtension
implementuje funkcjonalność DataView
rozszerzoną o rozszerzenie bezpieczeństwa obiektów.
O ile to możliwe, infrastruktura DataView
przekazuje wywołania metod dla atrybutów i relacji rozszerzenia obiektu biznesowego z DataView
do bazowego obiektu biznesowego. W poniższych przypadkach konieczne jest jednak programowanie w rozszerzeniu DataExtension
:
- dostęp do atrybutów wirtualnych
- dostęp do atrybutów podlegających translacji (NLS)
- dostęp do wirtualnych lub obliczanych relacji
- dostęp do relacji do widoku obiektu zamiast obiektu biznesowego
- kontrola widoczności i zmienności pól w dostosowywanym interfejsie
Dostępy te są zaimplementowane w DataExtension
w taki sam sposób jak w DataObject
, jak opisano w rozdziale Implementacja obiektu DataObject.
DataExtension ma dostęp do atrybutów obiektu biznesowego, w tym atrybutów rozszerzeń obiektu biznesowego, za pośrednictwem DataView
lub DataAccess
. Infrastruktura DataView
zapewnia, że dostęp do zapisu jest możliwy tylko do atrybutów rozszerzeń obiektów biznesowych w jego własnej przestrzeni nazw.
Jeśli relacje z właściwością READ_ONLY lub MUTABLE lub atrybutami wirtualnymi są zdefiniowane w rozszerzeniu warstwy obiektu, powiązane metody DataView
lub DataAccess
nie mogą być używane w implementacji rozszerzenia DataExtension
. Jeśli mimo to metody te zostaną użyte, wystąpi błąd uruchomienia.
Encje APP można rozszerzyć o nowe funkcje za pomocą hooków. Na przykład, nowe zależności w encji APP są zwykle zarządzane w hookach stanowych. Instancja tego hooka stanowego może być odpytywana za pomocą gettera dla wielu widoków obiektów w DataView. Jeśli ten getter jest używany w DataExtension, hook stanowy należący do przestrzeni nazw rozwoju DataExtension jest zwracany przez getter.
Podobnie jak DataObject, DataExtension jest tylko pośrednikiem. Instancje DataExtension są częściowo tworzone podczas uzyskiwania dostępu do DataView. Dla obiektu biznesowego w encji APP może istnieć kilka DataObject z kilkoma DataExtension w tym samym czasie. Instancje DataExtension są często przebudowywane i odrzucane.
Implementacja DataExtension musi spełniać następujące warunki:
- DataExtension musi posiadać konstruktor bez parametrów
- jawny konstruktor nie jest konieczny
- konstruktor nie może zawierać złożonych obliczeń
- DataExtension nie może przechowywać własnego stanu
- DataExtension nie może wywoływać żadnych metod na DataView, które są zaimplementowane w tym samym DataExtension
Niewirtualna relacja wymaga implementacji w DataExtension, ponieważ obiekt biznesowy ItemFashionExtension jest logicznie zależny w jednostce biznesowej.class ItemExtension extends DataExtension<ItemView, ItemAccess> {
public short getXyz_derivedState() {
return
getView().getSalesStatus()*100+
getView().getInventoryStatus();
}
DataObject<FashionExtension> retrieveXyz_ItemFashionExtension() {
XyzItemEntityState state =
(XyzItemEntityState)getView().getEntityState();
return new DataObject<FashionExtension>
(state.getFashionExtension());
}
}
DataDescriptionModification
Widoczność i zmienność pól dostosowywanego interfejsu jest kontrolowana w DataExtension lub w DataObject poprzez DataDescriptionModification
. Jeśli kilka źródeł generuje różne DataDescriptionModifications
dla tego samego pola, są one automatycznie łączone.
DataDescriptionModification dla bieżącego widoku obiektu
Aby zmienić DataDescriptionModification dla atrybutów widoku obiektu, do którego należy DataObject lub DataExtension, należy nadpisać metodę getDataDescriptionModification(Enum)
. Metoda ta jest przeznaczona do identyfikacji DataDescriptionModification
dla atrybutu bieżącego widoku obiektu.
W implementacji należy upewnić się, że metoda ta jest wywoływana dla wszystkich atrybutów, w tym atrybutów z rozszerzeń zewnętrznych.
Jeśli tylko niektóre pola mają mieć wpływ, można zastosować następujący wzorzec:
public DataDescriptionModification getDataDescriptionModification(Enum attribute) { switch (((CountryView.Attribute) attribute)) { case $ado_countryEuroCurrency: if (!getView().isEuMember()) { return DataDescriptionModification.READ_ONLY; } break; } return super.getDataDescriptionModification(attribute); } Aby wpływać na wszystkie własne pola, ale bez pól zewnętrznych, można użyć metody isAssociated(), aby sprawdzić, czy atrybut pochodzi z własnej aplikacji lub adaptacji. public DataDescriptionModification getDataDescriptionModification(Enum attribute) { if ( !isAssociated(attribute)) { return super.getDataDescriptionModification(attribute); } else if ( !isEnabled()) { return DataDescriptionModification.EXCLUDED; } if (attribute==Item.Attribute.$xyz && isX()) { return DataDescriptionModification.READ_ONLY; } else { return DataDescriptionModification.UNMODIFIED; } }
DataDescriptionModification dla zdalnych widoków obiektów
Aby zmienić DataDescriptionModification
dla atrybutów widoków obiektów, do których można dotrzeć poprzez relacje 1:1, zaczynając od bieżącego widoku obiektu, należy zaimplementować interfejs DataObject.DataDescriptionModificationProvider
z metodą getDataDescriptionModification(Path)
. Metoda ta ma na celu określenie DataDescriptionModification
dla ścieżki opartej na bieżącym widoku obiektu.
Podczas implementacji metody getDataDescriptionModification(Path)
należy pamiętać, podobnie jak w przypadku metody getDataDescriptionModification(Enum)
, że można wpływać na właściwości atrybutów zewnętrznych.
Należy pamiętać, że ścieżki niekoniecznie są unikalne. Kilka różnych ścieżek może prowadzić z tego samego widoku obiektu do tego samego miejsca docelowego. Dlatego, jeśli to możliwe, należy porównywać tylko odpowiednie części ścieżki, ale nie całą ścieżkę. Ścieżka oferuje w tym celu metody startsWith, endsWith
i contains
.
public DataDescriptionModification getDataDescriptionModification(Path path) { if ((! isMyAddressEnabled()) && path.contains(Relations.$MyAddress)) { return DataDescriptionModification.DISABLED; } return DataDescriptionModification.UNMODIFIED; }
Dalsze opcje
Komponenty GUI
Komponenty GUI mogą być również dostępne w konfigurowalnym interfejsie. Mogą być widokami z kilkoma polami, tabelą lub listą. W trybie projektowania komponent GUI jest umieszczany jako całość w interfejsie użytkownika aplikacji.
W widoku obiektu komponent GUI jest reprezentowany przez wirtualny atrybut boolean, jak w poniższym przykładzie. Logiczny typ danych atrybutu wirtualnego musi być oparty na typie danych boolean.
<virtualattribute property="READ_ONLY"> <name>xyz_address</name> <datatype>com.xyz.ext.app.addon1.AddressComponent</datatype> </virtualattribute>
Metody dostępu do atrybutu wirtualnego muszą być zaimplementowane w DataObject lub DataExtension. Komponenty GUI nie otrzymują swoich danych poprzez te metody dostępu, ale poprzez widok obiektu, który jest dostępny w AttriubteContext w komponencie GUI.
Tabele lub listy, w których mają być wyświetlane dane relacji 1:n, mogą być realizowane za pomocą klas PGM CisObjectContainer
(przechowywanie danych) i ContainerTableEditor
(komponent GUI).