Wprowadzenie
W niniejszym artykule opisano generowanie jednej lub kilku klas Java przez Kernel dla Business Objects i Parts. W kontekście generowania kodu, przedstawiono podobieństwa Business Objects i Parts oraz ich specyficzne cechy.
Grupa docelowa
- Deweloperzy
Wymagania wstępne
Wymagana jest znajomość Persistence service.
Definicja
Persistence service – działa wyłącznie z obiektami nieprzechodnimi. Jeśli Persistence service załaduje obiekt z bazy danych, obiekt ten jest nieprzechodni i trwały. Jeśli obiekt jest nowo generowany przez Persistence service i nie jest jeszcze przechowywany w bazie danych, wówczas obiekt ten jest nieprzechodni i nietrwały. Przejściowa kopia każdego obiektu może zostać utworzona niezależnie od jego statusu. Na przykład przejściowa kopia trwałego obiektu zawiera również informację, że obiekt jest trwały, ale brakuje odniesienia do bazy danych.
Obiekty nietrwałe – nie są jeszcze przechowywane w bazie danych.
Obiekty nieprzechodnie – obiekty nietrwałe posiadają kontekst transakcyjny, a zatem posiadają odniesienie do bazy danych. Obiekty nowo wygenerowane przez Object Manager nie są trwałe ani przejściowe.
Obiekty trwałe (persistent)- są przechowywane w bazie danych i z niej są ładowane.
Obiekty przejściowe (transient) nie mają kontekstu transakcji, a zatem nie mają odniesienia do bazy danych. Przejściowa kopia trwałego obiektu zawiera informację, że obiekt jest trwały, ale brakuje odniesienia do bazy danych.
Podobieństwa między Business Objects oraz Parts
- Właściwości, metody i obiekty są dziedziczone przez Business Objects oraz Parts zmienne (mutable) z klasy com.cisag.pgm.datatype.CisObject.
- Właściwości, metody i obiekty są dziedziczone przez Parts niezmienne (immutable) z klasy com.cisag.pgm.datatype.CisPart.
Obiekty biznesowe i zmienne Parts mają pewne podobieństwa, częściowo ze względu na identyczną klasę bazową, które opisano poniżej.
Ponieważ zmienne Parts i obiekty biznesowe mają tę samą klasę bazową, istnieją metody, które są zadeklarowane w klasie bazowej, ale nie są nadpisywane w klasie pochodnej. Metody te, takie jak getMutableCopy() obiektu biznesowego, wywołują wyjątki (wyjątek nieobsługiwanej operacji). Należy zatem sprawdzić zaimplementowane metody przed ich użyciem. W tym celu należy użyć kontekstu użycia lub zapytać o typy obiektów.
Zapytanie o metadane
W klasie CisObject można zapytać o typ obiektu tylko za pomocą metody:
public short get_type();
Wartość zwracana przez tę metodę odpowiada – w zależności od typu obiektu – jednej z poniższych stałych:
- T_BUSINESS_OBJECT
- T_MUTABLE_PART
- T_VIEW
- T_BUSINESS_ENTITY
- T_BUSINESS_SUBENTITY
W celu zweryfikowania, czy obiekt jest określonego typu, stosowana jest metoda:
public byte[] get_classGuid()
Flagi dla stanów przejściowych i trwałych
Za pomocą poniższych metod możliwe jest sprawdzenie, czy jest persistent czy transient:
public boolean is_persistent()
public boolean is_transient()
Flaga persistent może być ustawiona dla obiektów transient za pomocą tej metody:
public boolean set_persistent(boolean value)
Za pomocą metody
public boolean is_newObject()
można sprawdzić, czy obiekt jest już zarejestrowany w Menedżerze obiektów. Obiekt jest nowy tylko wtedy, gdy został utworzony za pomocą READ_WRITE lub INSERT i nie został jeszcze przesłany do Object Managera za pomocą putObject.
Metody kopiowania
Zawartość obiektu jest kopiowana do innej instancji (tej samej klasy lub instancji pochodnej) przy użyciu następującej metody:
public void copyTo(CisObject obj)
W przypadku obiektów zależnych od czasu wpis dotyczący okresu ważności nie jest kopiowany.
Zasady kopiowania w zależności od stanu obiektu docelowego:
-
Jeśli obiekt docelowy jest transient, wówczas do obiektu docelowego kopiowana jest kompletna zawartość obiektu źródłowego, łącznie z flagami persistent oraz deleted.
- Jeśli obiekt docelowy nie jest transient, wówczas do tego obiektu nie jest kopiowany ani klucz główny, ani żadne inne flagi.
Metody Equals
Za pomocą tej metody można porównać zawartość dwóch obiektów:
boolean contentEquals(Object obj)
Następująca metoda equals jest używana Business Objects oraz Parts:
boolean equals(Object object)
Metoda ta prowadzi do różnych wyników, w przypadku:
- Business Objects porównywany jest klucz podstawowy i flaga „transient”.
- Parts wywoływana jest następująca metoda:
contentEquals
Serializacja
Stan obiektu może być serializowany w tablicy bajtów (Byte-Arrays). Serializacja zapewnia pełną kopię zawartości obiektu. Oznacza to, że Parts i Arrays zawarte w obiekcie są również kopiowane.
Podczas serializacji możliwe jest określenie, czy ma zostać zapisany cały obiekt (changesOnly = false), czy jedynie te elementy, które zostały zmienione w bieżącej transakcji (changesOnly = true). Serializacja pełnego obiektu lub jego części odbywa się za pomocą metody:
public byte[] serialise(boolean changesOnly)
Deserializacja
Zserializowany obiekt można deserializować na dwa sposoby:
- Kopiując zawartość tablicy bajtów (Byte-Arrays) do istniejącej instancji tej samej klasy. Oznacza to, że zawartość wcześniej zserializowanego obiektu jest zapisywana do istniejącej instancji. W tym celu należy użyć tej metody:
public void deserialise(byte[]array)
Jest ona podobna do metody copyTo, ale serializowana Byte-Arrays zawiera również zakresy obiektów zależnych od czasu.
- Generowana jest nowa instancja z zawartością tablicy bajtów (Byte-Arrays). Za pomocą tej metody generowana jest instancja serializowanej klasy:
public static CisObject create NewInstance(byte[]array)
public static CisObject create NewInstance(byte[]array)
Parts
Poniższa metoda tworzy „głęboką kopię” części:
public CisObject copy()
Dostęp do immutable (niezmiennych) części
Immutable Part stanowi otoczkę (wrapper) dla mutable Part. Podczas przekształcania mutable Part w immutable Part dostępne są dwa podejścia:
Generowanie nowego wrappera dla istniejącego mutable Part
- public CisPart castImmutable() - public static <<Part>> castImmutable(<<PartMutable>> partMutable) - public static <<Part>>[] castImmutable(<<PartMutable>>[] partMutable)
Tworzenie głębokiej kopii mutable Part
- public static <<Part>> getImmutableCopy (<<PartMutable>> partMutable) - public static <<Part>> getImmutableCopy (<<PartMutable>>partMutable)
Metody static (statyczne) każdorazowo sprawdzają, czy argument jest null.
Jeśli przekazany argument ma wartość null, zwracana wartość również jest null.
Różnice
castImmutable
Metoda castImmutable nie tworzy kopii. Dlatego atrybuty immutable Part mogą ulegać zmianie, jeśli zmieniany jest odpowiadający mu mutable Part.
copyImmutable
Immutable Part jest zapisywany w oddzielnym mutable Part. Immutable Part kapsułkuje mutable Part. Dzięki temu żaden program nie może zmodyfikować immutable Part.
Dostęp do mutable Parts
Mutable Part jest otoczony przez immutable Part. Po wygenerowaniu immutable Part dostęp do mutable Part nie jest już możliwy. Z tego powodu może zostać wygenerowana jedynie kopia mutable Part, która zawiera treść immutable Part. Następujące metody generują mutable Parts:
public CisObject getMutableCopy()
public static <<PartMutable>> getMutableCopy (<<Part>> part)
public static <<PartMutable>>[] getMutableCopy (<<Part>>[] part)
Metody static sprawdzają każdorazowo, czy argument ma wartość null. Jeśli przekazany argument jest null, wynik również ma wartość null.
Business Objects
Dla każdej instancji Business Object możliwe jest pobranie iteratora zawierającego wszystkie istniejące instancje przy użyciu następujących metod:
public CisObjectIterator retrieve_instances()
public CisObjectIterator retrieve_instances(int flags)
Referencja do Business Object jest pobierana za pomocą metody:
byte[] get_objectReference()
Referencję można pobrać jedynie dla persistent Business Objects.
Pobrana referencja zostaje załadowana do Business Object i jest ważna tylko wtedy, gdy transakcja została zakończona instrukcją commit.
Klucze (keys)
Wszystkie Business Objects zawierają metody statyczne umożliwiające generowanie różnych kluczy. Klucze mogą być tworzone również dla obiektów, które jeszcze nie istnieją. Metody statyczne odpowiedzialne za generowanie kluczy znajdują się w klasie Business Object, do którego dany klucz należy. Ich struktura ma następującą postać:
<<BusinessObject>>.build<<KeyName>>Key(<<KeyAttribute 1>>,...,<<KeyAttribute n>>)
Nazwa klucza głównego zawsze rozpoczyna się od Primary. Oznacza to, że klucz główny może zostać wygenerowany przy użyciu metody:
buildPrimaryKey
Klucz główny instancji Business Object można pobrać z poziomu tej instancji poprzez:
public byte[][] get_uniqueKeys()
Instance String to tekstowa reprezentacja instancji Business Object, ułatwiająca jej zrozumiałą identyfikację dla użytkownika, np. Odbiornik radiowy art. 4711.
Atrybuty użyte do stworzenia Instance String znajdują się również w Business Key. Pobranie Instance String odbywa się za pomocą:
public String get_instanceString()
Po pierwszym przekazaniu instancji Business Object do Object-Managera przy użyciu putObject, atrybuty klucza głównego tej instancji nie mogą być już zmieniane.
Relacje
Między Business Objects oraz między Part a Business Objects mogą istnieć relacje. Rozróżnia się relacje 1:1 oraz 1:n. Dla każdej relacji generowana jest metoda retrieve w obiekcie, z którego relacja wychodzi. Za pomocą metody retrieve można pobierać referencjonowane Business Objects. Jeśli obiekty zawierają atrybuty NLS, referencjonowane obiekty są ładowane w następujący sposób dla:
- Business Objects referencjonowane obiekty są ładowane w języku, w którym został załadowany obiekt źródłowy.
- Parts referencjonowane obiekty są ładowane w języku bazy danych.
Metody retrieve dla relacji 1:1 są generowane w następujący sposób:
<<BusinessObject>> retrieve<<nazwa relacji>>()
<<BusinessObject>> retrieve<<nazwa związku>>(int flags)
Metody retrieve dla relacji 1:n są generowane w następujący sposób:
CisObjectIterator retrieve<<nazwa relacji>>()
CisObjectIterator retrieve<<nazwa związku>>(int flags)
Opcjonalny parametr flags określa, w jaki sposób obiekt ma zostać załadowany. Odpowiednie stałe (READ, READ_UPDATE, …) znajdują się w Object-Manager.
Metody kopiowania
Każde persistent Business Object jest ważne wyłącznie w ramach tej transakcji, w której zostało załadowane przez Object Manager. Jeśli konieczne jest użycie Business Object, które nie powinno zależeć od żadnej transakcji, należy wygenerować jego kopię transient za pomocą poniższych metod:
public static <<BusinessObject>> getTransientCopy(<<BusinessObject>> object)
public static <<BusinessObject>> getTransientCopy(<<BusinessObject>> object)
public static <<BusinessObject>>[] getTransientCopy(<<BusinessObject>>[] object)
Metody static każdorazowo sprawdzają, czy przekazany argument ma wartość null. Jeśli argument jest null, zwracany wynik również ma wartość null.
Atrybuty możliwe do zlokalizowania
W momencie ładowania Business Object możliwe jest określenie języka, w którym mają zostać zwrócone atrybuty możliwe do zlokalizowania. Język, w którym takie atrybuty zostały załadowane, można sprawdzić za pomocą następującej metody:
public String get_contentLanguage()
Zależność czasowa
Za pomocą poniższej metody można sprawdzić, czy Business Object jest obiektem zależnym od czasu:
boolean is_timeDependent()
Dla obiektów zależnych od czasu, niezależnie od rodzaju ich zależności czasowej, generowane są następujące metody:
public java.util.Date getValidFrom()
public void setValidFrom(java.util.Date validFrom)
public java.util.Date getValidUntil()
public void setValidUntil(java.util.Date validUntil)
Przedział czasu [validFrom, validUntil[ obiektu zależnego od czasu można odczytać lub zmienić za pomocą tych standardowych metod.
W tym przypadku dolny limit validFrom jest zawarty w przedziale ważności, podczas gdy górny limit validUntil nie jest zawarty w przedziale ważności.
W przypadku obiektów zależnych od czasu może wystąpić sytuacja, w której istnieje wiele obiektów z takim samym kluczem głównym lub kluczem wtórnym, pod warunkiem że posiadają one rozłączne interwały obowiązywania.
Standardowy klucz główny nie zawiera atrybutu validFrom, dlatego dostępne są metody pozwalające pobrać lub wygenerować odpowiedni klucz dla obiektu zależnego od czasu.
W przypadku zależności czasowej typu:
- data ze strefą czasową (zarządzana przez aplikację)
- czas ze strefą czasową (zarządzany przez aplikację)
generowany jest dodatkowy atrybut:
- _timeZoneGuid
Atrybut ten ma takie samo znaczenie, jak w przypadku Object-Dates lub Object-Timestamps.
Atrybuty validFrom oraz validUntil nie są typu CisDate.
Ten klucz jednoznacznie identyfikuje Business Object wraz z jego interwałem obowiązywania:
public byte[] get_timeDependentKey()
public byte[] buildTimeDependentKey(<<PrimaryKey>>, java.util.Date validFrom)
Dla obiektu zależnego od czasu możliwe jest pobranie czasowo następnej lub poprzedniej wersji Business Object przy użyciu następujących metod:
public <<BusinessObject>> retrieve_nextVersion()
public <<BusinessObject>> retrieve_nextVersion(int flags)
public <<BusinessObject>> retrieve_previousVersion()
public <<BusinessObject>> retrieve_previousVersion(int flags)
Informacje o zmianach
Aby sprawdzić, czy informacje o aplikacji powinny być przechowywane dla Business Object należy użyć metody:
boolean is_updateInfoRequired()
Następujące metody są generowane dla obiektów z informacjami o zmianach:
public UpdateInformation getUpdateInfo()
public UpdateInformationMutable getMutableUpdateInfo()
public void setUpdateInfo(UpdateInformationMutable _updateInfoInstance)
Informacje o zmianach obiektu mogą być odczytywane i modyfikowane za pomocą standardowych metod. Na podstawie informacji o zmianach można ustalić, kiedy i przez którego użytkownika Business Object zostało utworzone, ostatnio zmodyfikowane lub oznaczone jako usunięte. Oznaczenie jako usunięte nie oznacza fizycznego usunięcia obiektu z bazy danych. Do oznaczenia obiektu jako usuniętego służy metoda:
public void set_deleted(boolean value)
Metoda ta ustawia jedynie flagę usunięcia (data usunięcia w informacjach o zmianach staje się różna od null). Dzięki temu aplikacja może wizualnie wyróżniać obiekty oznaczone jako usunięte. Aby sprawdzić, czy obiekt został oznaczony jako usunięty, służy metoda:
public boolean is_deleted()
Metody:
is_deletedset_deleted
są również dostępne dla obiektów, które nie mają informacji o zmianach. W tym przypadku jednak metody te mogą być używane tylko dla obiektów transient.
Business Entities
Jeśli Business Object jest Sub-Entity lub Dependent, możliwe jest pobranie powiązanego Business Entity za pomocą następujących metod:
public CisObject retrieve_entity()
public CisObject retrieve_entity(int flags)
Informacje o dacie i godzinie ze strefą czasową
Czas oraz daty z informacją o strefie czasowej są przechowywane w klasie Java
com.cisag.pgm.datatype.CisDate
Obiekt CisDate składa się czasu oraz przypisanej do niej strefy czasowej.
W przestrzeni nazw com.cisag.pgm.datatype znajdują się różne typy danych umożliwiające wykorzystanie atrybutu CisDate w Business Object lub Part.
W kodzie generowanym rozróżniane są następujące typy:
CisObjectDate oraz CisObjectTimeStamp CisAttributeDate oraz CisAttributeTimeStamp
Wszystkie CisObjectDates w jednym Business Object muszą korzystać z tej samej strefy czasowej.
Strefa czasowa dla CisObjectDates jest przechowywana w atrybucie:
-
timeZoneGuid – atrybut timeZoneGuid może zostać ustawiony jedynie podczas tworzenia nowego Business Object.
Po jego pierwszym ustawieniu nie może być już zmieniany w obiektach, które nie są transient.
Każda próba ponownego ustawienia wartości prowadzi do błędu wykonania.
Jeśli w Parts wykorzystywane są CisObjectDates, strefa czasowa jest weryfikowana dopiero w momencie przypisania instancji Part do atrybutu Business Object.
Jeśli CisDate o innej strefie czasowej zostanie przypisany do atrybutu typu CisObjectDate, wystąpi błąd wykonania.
Waluty bazowe
Jeśli w Business Object wykorzystywane są waluty bazowe (DomesticAmounts), wówczas do obiektu generowane są dodatkowe atrybuty:
-
_organization (GUID) – GUID jednostki organizacyjnej, do której odnoszą się wszystkie waluty bazowe w Business Object podczas konwersji.
-
_conversionDate (TimeStamp) – moment wykonania konwersji.
-
_currencyCombo (short) – używana kombinacja walut.
Atrybuty te są wykorzystywane przede wszystkim podczas reorganizacji jednostek organizacyjnych lub zmiany kombinacji walut.



