This is part two of my five-part tutorial about implementing a web-based database application with the OlivaNova Modeler (check out the running application: http://www.blogger.com/post-edit.g?blogID=2481650812860323753&postID=4842178084421971171#). In this part, we are going to discuss a rather simple task, the creation of classes, attributes, associations and inheritance. If you are interested, you might want to check out Part one: introduction and specification.
First of all, let’s start with the "static" model. Here, we are going to define classes and their relationships to each other quite similar to the way you are used to doing in UML.
We are going to define the following classes: Administrator, Employee, Manager, Car, Receipt, TravelApplication (=trip request), Department, TravelCostGroup, ReceiptType, CostCenter, CostUnit.
In the next step, we are going to specify the classes’ attributes. For simplicity sake, let’s start with Employee.
Defining class attributes
We double-click on the class Employee and the following dialog pops up:
I already entered the attributes according to the current specification (the final model contains some more calculated attributes for statistical purposes according to the specification). I highlighted the attribute EmployeeID for demonstration purposes.
- The name must not start with a number and must not contain white spaces or special characters.
- Attribute type can be Constant, Variable or Derived. “Constant” means, that the value cannot be changed after the object has been created. Variable means the opposite. “Derived” means that the attribute value is calculated through a formula. In this case, the EmployeeID won’t change (its supposed to be the AD login domain\username).
- As the EmployeeID is in domain\username format, its datatype has to be String.
- Id:0 means that the attribute is part of the objects primary key. I really don’t know why the guys who implemented the modeller made such a crappy feature , nevertheless it works just fine.
- Size means (as you might already have guessed) the maximum length of the string attribute value that can be entered, processed and stored.
- Optionally you can define a default value that is used if the user doesn’t change it.
- Null allowed is self-explanatory.
- Request upon creation means, that the method that is used for object creation contains this attribute as an argument.
- The alias is a string that represents a more end-user friendly name for the attribute and can also contain white spaces and special characters etc.
Finally, you can enter a help message for the attribute and a comment for the analyst who is going to maintain the model. If you add help messages, the text will be displayed as a tooltip text in the generated user interface in service forms.
In this same way, all other classes get their attributes, but again because I don’t want to bore you, I skip this section and we go straight to doing something more interesting.
Establishing relationships and inheritance
Now that we have defined our classes, we need to define relationships between those classes. Remember, we didn’t define the car license number as a primitive datatype (although we could) because we know the cars in our car pool and want to be able to manage them and want to eliminate typos when entering the same car license number over and over again. That is why we have created a class Car which we can use as a dropdown data source.
Relationships work almost in the same way as in UML. However, there is one annotation you probably don’t already know: each relationship is labeled with it's cardinality and the letter “D” or “S”. “D” means, that you can change the number of associated objects after an object creation while “S” means just the opposite.
So, if you read the association between Receipt and ReceiptType, it means that a Receipt needs to have exactly one ReceiptType and the ReceiptType cannot be changed after the creation of an object of type Receipt. A ReceiptType object may have zero or more Receipts associated and those associations can change at any time during the lifetime of the object.
So, this was rather easy, wasn't it? And you might ask yourself where and how the functionality is modeled or if I programmed those requirements secretly by hand.
In part three of my tutorial you'll find out how the business logic is being implemented in the modeler.
Stay tuned :-)