Web Application Example PDF
Web Application Example PDF
5
Web Application Example
MetaCase Document No. WA-4.5
Copyright © 2008 by MetaCase Oy. All rights reserved
First Printing, 1st Edition, September 2008.
MetaCase
Ylistönmäentie 31
FI–40500 Jyväskylä
Finland
Preface
The web application example illustrates how UML can be used (and abused!) to specify web
applications, and how complete working applications can be produced from those models. To
achieve this, a domain-specific generator is implemented into MetaEdit+. Unlike the standard
generators supplied with UML tools, which can only create class and method skeletons, this
generator produces the full code that we want for each application.
Using the example, a developer can design simple database web applications using the
familiar core concepts of UML. We will also see how going beyond simple examples requires
increasing amounts of twisting and redefining of UML semantics, resulting in a language that
is hard to use, and no longer “UML” in anything but notation.
Normally, a web application would be written in a server-side programming language. Since
you might not have a server handy, or perhaps don’t have the right to upload applications and
create databases, we will make this web application run purely in your browser. We will create
HTML pages for the user interface, JavaScript for the behavior, and use SQLite running in
Google’s Gears for the database.
To explore the web application example thoroughly, the following things are required:
MetaEdit+ for trying out the web application language. For further information about
MetaEdit+, please refer to the MetaEdit+ User’s Guide.
The web application patch, to add web application generators and example models to the
‘UML examples’ project in the MetaEdit+ demo repository.
Internet Explorer or Firefox, with JavaScript support enabled.
Google’s Gears framework, which you will automatically be prompted to download and
install when opening the first generated web application. Gears is a small add-on to your
browser, offering an SQLite database inside the browser (among other things).
We expect that you have a working knowledge of MetaEdit+. If you want to extend the DSM
language or generators further you should have MetaEdit+ Workbench or the evaluation
version available from http://www.metacase.com.
4 MetaEdit+
Web application example
The web application example breaks the rules of DSM – but in a good cause. Most developers
have seen UML used for specifying databases: classes map to tables and attributes to columns.
What UML can’t do so well is specify behavior: even if we enter the names and parameters of
operations, or add a state diagram, we have only shown how we want to break that behavior
down into chunks, but still UML has not helped us create the contents of those chunks. But
what if we could do without behavior altogether? Or to be more precise, if we could specify
behavior once for a whole class of applications, and have each application follow that
behavior guided by its own data? If that were so, even the humble UML class diagram might
be enough to specify any of a range of useful applications.
Can an application’s behavior come from data? Of course, we are all familiar with this on a
simpler level. In some way, all applications are guided by their data: if we want to show the
surname of a person, we need to display different characters depending on whether the person
is John Smith or Jane Doe. The code doesn’t contain the data, just the variable names which
are replaced by data at runtime:
writeln("First Name: " + firstname);
writeln("Surname: " + surname);
writeln("Age: " + age);
We can go a step further, though: rather than writing code like the above, we can write generic
code that says “print all attributes and their values”:
for (i=0; i<attributes.length; i++){
writeln(attributes[i] + ": " + values[i];
}
With code like that, we can supply any number of any kind of attributes, and things will just
work. For example:
var attributes = [
{name:"First Name", datatype:"string"},
{name:"Surname", datatype:"string"},
{name:"Age", datatype:"int"}
];
var values = ["John", "Smith", 43];
We thus have data (values) but also data about that data (attributes). Data about data is
often called meta-data, and programming that takes advantage of it is called meta-data
programming. With a little meta-data programming we can specify the generic behavior of
simple database web applications once, and let the rest be generated from the models.
In this first chapter we show how to install the web applications example and try it out on a
sample model to see how the generated application works in practice. Chapter 2 looks at how
UML is used for this example, and the limitations of UML when going beyond simple web
applications. Chapter 3 describes how the generator and domain framework were defined.
Please note that testing the modeling language and models presented here requires basic
knowledge on how to use MetaEdit+.
1.2 AN EXAMPLE
Select UML examples in the Projects list and double-click Football in the Graphs list to open
the following Class Diagram:
6 MetaEdit+
Web application example
After creating some players for the teams, you might have something like this:
8 MetaEdit+
How UML is used for these web applications
The core modeling concepts of UML are hopefully familiar. We only use Class Diagrams, and
within them only Classes, their Attributes, Associations and Aggregations; inheritance is
ignored. Attributes can have data types of string (the default, mapping to varchar(255)) or
integer (int is also accepted), and can specify default values (with no quotes). Relationships
are always one-to-one or one-to-many, i.e. at most one end can specify a cardinality greater
than one (0..*, 1..*, *). An Association role or Part must be marked as Navigable for that link
to show up in the web forms; Association roles show an open arrow when Navigable, Parts do
not. (At least not in standard UML notation: with MetaEdit+ you can of course change the
Part symbol definition.)
10 MetaEdit+
Generators and domain framework
To best understand a modeling language, you need an example model. Similarly, to best
understand a generator, you need the code generated from an example model. We will look
here at the Football example, which is composed of the following files:
File Description Same for
all apps?
Football.html The home page for the application, with a model screenshot No
Team.html The main HTML page for Teams with the data entry form No
TeamList.html The HTML page to list all Teams No
*.html, *List.html Corresponding HTML pages for Player, League and Match No
sample.css The Cascading Style Sheet Yes
gears_init.js Google’s initialization code for Gears Yes
sample.js Google’s utility functions and Gears installation prompt Yes
globals.js JavaScript global variables and functions Yes
entry_common.js JavaScript functions for form and list pages Yes
entry_form.js JavaScript functions for form pages Yes
The generators and their subgenerators are shown below. Team.html is generated by _Entry
and its subgenerators – and similarly for each class: Player, League and Match. TeamList.html
is generated by _EntryList. Football.html is generated by the _App generator.
We will concentrate on Team.html, as seen in Figure 1-4. At the start of Team.html is the form
for entering the data for a team. The list of 4 recent entries at the bottom of the page is largely
reused as the content of TeamList.html. The rest of the HTML file includes the script files
above, and provides the meta-data and code needed for Teams. Below, we will go through
these sections in more detail, showing the link between the model, generators, and generated
code.
Each Team has a reference to one League, so the page for Team includes a list for selecting
the appropriate League, along with a button to jump to the page to edit that League. The
HTML for these is generated by _EntryHTMLforeignFields, resulting in the following:
<td class="foreignLabel">League</td>
<td>
<select id="fk_League" style="width:20em;"></select>
</td>
<td>
<button type="button"
onclick="editForeign('fk_League');"
id="fk_LeagueButton">
Edit
</button>
</td>
The set of choices in the field will be set later by JavaScript. The meta-data specifying the
links to other pages is generated later by _EntryJSVariable into global variables
wholeForeign and assocForeign, which are in turn concatenated into allForeign.
In this case, there are no Aggregation / Whole-Part relationships, so wholeForeign is
empty.
// Links from this table to another table by a foreign key
wholeForeign = [];
assocForeign = [
{name:"fk_League",pageName:"League",foreignCols:["name"]}
];
12 MetaEdit+
Generators and domain framework
_EntryHTMLform generates a table row, label and input field for each Attribute:
<tr>
<td class="label">name</td>
<td valign="middle">
<input type="text" id="name" style="width:20em;">
</td>
</tr>
<tr>
<td class="label">nickname</td>
<td valign="middle">
<input type="text" id="nickname" style="width:20em;">
</td>
</tr>
<tr>
<td class="label">shirtColor</td>
<td valign="middle">
<input type="text" id="shirtColor" style="width:20em;">
</td>
</tr>
The meta-data specifying the local columns in this database table is generated later by
_EntryJSVariable into global variable cols.
// Simple local columns in this table
cols = [
{name:"name",datatype:"varchar(255)",defaultValue:""},
{name:"nickname",datatype:"varchar(255)",defaultValue:""},
{name:"shirtColor",datatype:"varchar(255)",defaultValue:""}
];
Below the input fields, _EntryHTMLforeignTable generates the HTML for tables listing
such one-to-many linked entries:
<tr>
<td class="foreignTableLabel">Players</td>
<td>
<table class="foreignTable" id="PlayerTable">
<tbody></tbody>
</table>
</td>
</tr>
In the generated HTML, there is only an empty placeholder table: the content, including the
buttons and column headers, is filled in at runtime by the JavaScript function
displayForeignRows in entry_form.js. Although the header row could have been
generated as static HTML, the meta-data about the columns is needed anyway for filling in
subsequent rows. It was thus easy enough to use the same code and meta-data to create the
header row too.
The meta-data specifying the foreign key columns in other database tables that point to this
table is generated later by _EntryJSVariable into global variable
referredAsForeign.
// Links to this table from another table as a foreign key
referredAsForeign = [
{name:"fk_Team", pageName:"Player", tableName:"tbl_Player",
foreignCols:["firstName", "lastName"]
}
];
14 MetaEdit+
Generators and domain framework
<table id="listTable">
<tbody></tbody>
</table>
<p>
<button type="button" onclick="gotoNew();">New</button>
<button type="button" onclick="gotoList();">View All</button>
<button type="button" onclick="dropDBTable();">Delete All</button>
</p>
16 MetaEdit+
Conclusion
4 Conclusion
In this example, we have demonstrated how domain-specific generators can help even a
general purpose modeling language. Of course, to take things further the next step would be to
create a proper domain-specific modeling language, taking into account the kinds of web
applications you want to build. Many people have built such modeling languages, which can
be divided into three categories:
1) for the in-house use of the organization that created them;
2) available as commercial tools, such as Skyway, AppVenture, and IronSpeed;
3) for anyone to use, such as WebML.
As we move down the list above, the languages try to reach a broader market and thus become
less domain-specific – and hence cannot be as tight a fit with your own requirements on the
kinds of applications you want or the kind of code you want. Conversely, the less experience
you have with web applications, the more you are likely to accept someone else’s “one size
fits all” solution.
In a slightly different approach, the databases can be specified in online forms or wizards
rather than a graphical modeling language, and the resulting application can be automatically
hosted online, insulating you still further from technical issues: examples include Caspio and
the impressive DabbleDB.
The defining question for your choice of technology is this: how much do you know about
building web applications? The less you know, the more likely you are to be happy that some
tool has already made many decisions for you. Conversely, the more you know, the less likely
you are to be satisfied with the one-size-fits-all solutions of existing tools – or then if the
existing tool offers many solutions, the more frustrated you are likely to be with having to fill
in a myriad of forms and wizards, when you feel you could achieve the same results as quickly
by hand coding. If you are building many web applications, the tools would force you to jump
through the same hoops again for each application: at least with hand coding you could reduce
the work by abstracting some common parts of your solution into frameworks.
If the choice was just between off the shelf tools and hand coding, most people who were
capable would code their own web applications. That indeed is what generally happens today.
With domain-specific modeling tools, there is a third choice: abstract the common parts still
further. The parts that describe what kinds of applications you want to build go into the
modeling language, your framework becomes a domain framework, and the instructions for
how to use the framework are built into the generator. Now, you can build web applications of
exactly the kind that you want, faster than in any of the previous ways. You can also give the
modeling language to other people, who might be skilled at designing web applications but not
at implementing them. In all likelihood, those people will prefer a modeling language other
than UML.