LicenseList Structure

<< Click to Display Table of Contents >>

Navigation:  PUM - Modellierung und Codeerzeugung > Strukturen und Muster >

LicenseList Structure

Beschreibung

Diese Struktur ermöglicht die Abfrage von Lizenzinformationen (auch mehrere). Die Aufgabe des Entwicklers besteht darin, die verschiedene Quellen  zu ermitteln oder zu erschaffen und diese  Informationen pro Lizenz in drei Attributen zu verdichten (in 2 String Infos und einem Datums-Attribut). Wenn weitere Attribute gewünscht werden - Modell einfach erweitern.

Diese Struktur fügt nur API-Strukturen ein und einen API-Call:

API-Model: xxxAPILicenseInfo

oName der Lizenz

oInfos über die Lizenz

oAblaufdatum der Lizenz

API-Call: SystemLicenseListRead

Die API-Informationen werden über eine CRUD-Struktur ermittelt - wobei nur der (R)ead-Teil zu implementieren ist ...

Beispielimplementierung

Anbei eine Beispielimplementierung des READ-Calls (in Smalltalk):

 

apiSystemLicenseListRead: aTSTAPIPRLicenseListStore options: aMSKRestCallOptions

 

 | aTSTAPILicenseListStoreRL aTSTAPILicenseInfo totalAPIResultList sortedTotalAPIResultList selectedAPIResultList gsLicenseInfo |

 

  "

   Der Parameter aTSTAPIPRLicenseListStore wird nicht wirklich benötigt - aber man 

   kann sich vorstellen, den Call später zu parametrisieren. Außerdem benötigt man 

   den Parameter als Paging-Information

  "

 

 

  "

   Wir checken ggfs. ob der Benutzer den Call überhaupt machen darf ... der

   eigentliche Check muss entsprechend kodiert werden: isAllowedToRetrieveLicenseInfo

  "

  aMSKRestCallOptions getUser isAllowedToRetrieveLicenseInfo

    ifFalse:[

      "Wir nutzen die vordefinierte Access Denied Exception"

      TSTEnumErrorDefinition errCodeAccessDeniedThrowSignal: aMSKRestCallOptions 

    ].

 

  "

   In allen PageRequests gibt es die folgende Reihenfolgen

 

     a) Ermittlung der Komplettmenge

     b) Filterung der Komplettmenge

     c) Sortierung der Komplettmenge

     d) Eventuelles Paging ausführen

 

   Dieses Beispiel ist besonders, denn die Rückgabeobjekte werden nicht von persistenten

   Objekten abgeleitet. Daher entfällt hier das Filtern. Die Sortierung muss manuell

   vorgenommen werden

  "

 

  "

    Zuerst die komplette Menge erstellen. Hier wird das manuell zusammengestellt - hier

    könnte man auch die Sortierung direkt mit einbinden ...

  "

  totalAPIResultList := OrderedCollection new.

 

  totalAPIResultList

    add: ((TSTAPILicenseInfo newInitialized setAllAttributesToNil)

            setName: 'Anwendung xyz' ;

            setInfo: ' ... gültig bis x/2023 ... ';

            ":-), immer vorm ablaufen ..."

         setDeathDate: (Date today);

            yourself.

 

   self retrieveGemstoneLicenseInformation ifNotNil: [ :aGsLicenseInfo | totalAPIResultList add: aGsLicenseInfo ].

 

  "

    Wir könnten nun noch sortieren ... um einheitliche Rückgabelisten zu erzwingen

  "   

  sortedTotalAPIResultList := SortedCollection sortBlock: [ :a :b | a getName < b getName ].

  sortedTotalAPIResultList addAll: totalAPIResultList.

 

  "

    Und dann noch ggfs. Paging

  "

  selectedAPIResultList := sortedTotalAPIResultList 

                              mskRestStart: aTSTAPIPRLicenseListStore getStart 

                              limit: aTSTAPIPRLicenseListStore getLimit 

                              page: aTSTAPIPRLicenseListStore getPage.

   

  "Wir bauen die Rückgabestruktur zusammen"

  ^(self restAnswerClass 

      okRequestFor: aMSKRestCallOptions restCallInstance 

      result:  (TSTAPILicenseListStoreRL withAPIList: selectedAPIResultList total: totalAPIResultList)) 

     "Wir ändern keine Daten - daher kann man auf ein Commit verzichten, und einfach ein Abort erzwingen"         

     successWithoutCommitCall;

     yourself

 

 

Weitere Codebeispiele

Gemstone Lizenz

Anbei eine Beispielimplementierung, um die Gemstone Lizenz auszulesen und eine geeignete Instanz zur weiteren Benutzung zurückzugeben:

 

retrieveGemstoneLicenseInformation

 |   aTSTAPILicenseInfo licensePath  aGSFile writeStream collectData sunsetData |

 

  licensePath := (System gemEnvironmentVariable: 'GEMSTONE'),'/seaside/etc/gemstone.key'.

  (GsFile existsOnServer: licensePath) isNil ifTrue:[ ^nil ].

  (aGSFile := GsFile openReadOnServer: licensePath) isNil ifTrue:[ ^nil ].

  writeStream := WriteStream on: Unicode16 new.

 

  collectData := false.

  [ aGSFile atEnd ] whileFalse: [

         | singleLine |

         singleLine := aGSFile nextLine.

 

         ((singleLine _findString: 'Sunset date' startingAt: 1 ignoreCase: true) > 2)

                 ifTrue: [ sunsetData := singleLine ].

 

         collectData 

                 ifTrue:[

                         (singleLine _findString: 'Customer name:' startingAt: 1 ignoreCase: true) > 2

                                 ifTrue:[ collectData := false ].

                 ]

                 ifFalse:[

                         collectData :=  (singleLine _findString: 'GemStone version:' startingAt: 1 ignoreCase: true) > 2

                 ].

 

         collectData

                 ifTrue:[ writeStream nextPutAll: singleLine ]

  ].

  aGSFile close.

 

  aTSTAPILicenseInfo := TSTAPILicenseInfo new initialize.

  aTSTAPILicenseInfo 

    setName: 'Gemstone DB'

    setInfo: writeStream contents.

 

  sunsetData notNil ifTrue:[  

   | readStream newString  |

 

    readStream := ReadStream on: sunsetData.

    readStream upTo: $:  .

    newString := readStream upToEnd trimBlanks.

 

    readStream := ReadStream on: newString.

    newString := (readStream upTo: $  ) trimBlanks.

 

    aTSTAPILicenseInfo

      setDeathDate: (Date fromString: newString usingFormat: #( 2 1 3 $/ 1 1 ))

  ].

 

  ^aTSTAPILicenseInfo