16 kwietnia 2008

Pierwsze kroki z UML w NetBeans 6.1

UML (Unified Modelling Language) nigdy nie należał do moich podstawowych narzędzi programistycznych, którymi posługiwałem się podczas tworzenia oprogramowania. Ostatnimi jednak czasy odczuwam niedosyt różnorodności sposobów przedstawiania swoich myśli i zauważam, że mowa (jakkolwiek wyćwiczona) nierzadko przedstawia je właściwie. UML jest językiem obrazowania idei i słowo obrazowanie, jakkolwiek nie stosowane szeroko w tym kontekście, jak najbardziej mi tu pasuje i wyraża, co autor miał na myśli. Język UML jest sposobem wizualnego przedstawiania myśli i pomaga w ich relacji innym. Warto się zainteresować UMLem i mimo nieczęstego użycia w naszych projektach, zacząć go stosować (nawet mimo braku jego użycia przez cały zespół projektowy, gdyż dobre rzeczy same się reklamują i raz zauważony w użyciu UML może stać się podstawowym językiem wymiany informacji). Więcej o UML na stronach "producenta" - http://www.uml.org.

Dzisiaj miałem przyjemność przeczytać wpis Expectation driven developement in NetBeans IDE 6.1 Beta, gdzie autor zastosował umlowy diagram klas do zademonstrowania, co będzie tworzył, a dalej, w komentarzach, znalazłem informację o wsparciu UMLa przez NetBeans 6.1. Dodając do tego moje (wciąż bierne) zainteresowanie UMLem i trwający konkurs NetBeans IDE 6.1 Beta Blogging Contest mogłem ponownie upiec dwie pieczenie na jednym ogniu - zapoznać się z UMLem i sprawdzić jego wsparcie w NetBeans 6.1, a w dodatku zgłosić mój wpis w konkursie (to w sumie daje aż 3 pieczenie na jednym ogniu!).

Zacząłem od lektury artykułu w sekcji UML NetBeansa - Why Model With UML?, gdzie napisano This article serves as a primer for the basic concepts of UML oraz This article is written for those engineers who can never find time to model a project before starting to code and for those engineers who have not yet considered creating models of their systems prior to coding them, aż w końcu This article presents some methods and strategies to help you be more efficient and possibly even save time. To jakby stworzone specjalnie dla mnie! Po 10 minutach miałem go za sobą. Mimo, że wiele tez przedstawionych w artykule było mi znanych, artykuł czytałem z wielkim zainteresowaniem. Obawiałem się początkowo, że będzie trochę przydługi, ale był w sam raz i zaprezentował UML w sposób nie pozostawiający złudzeń, że jest to obowiązkowy sposób na rozpoczęcie projektu, każdego projektu.

Kolejny artykuł w serii wprowadzenia UMLa to UML: Developing Applications. Trochę mnie przeraziło Expected duration: 25 minutes, ale pomyślałem, że skrócę tu i tam, abym jedynie rozeznał się gdzie i jak zacząć, aby ostatecznie przeczytać artykuł i samemu coś stworzyć. Podczas lektury artykułu zdecydowałem się go nieznacznie uatrakcyjnić, w ten sposób, że w artykule tworzona jest aplikacja desktopowa, a ja postanowiłem stworzyć aplikację webową. Oni desktopową, ja webową.

Nie siląć się na wymyślny przykład postanowiłem stworzyć aplikację webową, która będzie witała użytkownika w języku, który jest przez niego wybrany jako domyślny w przeglądarce.

Ctrl+Shift+N i z kategorii Web wybrałem Web Application.

Podałem dane projektu:

Project Name: PowitanieWebApp
Server: GlassFish V2
Context Path: /powitanie
Frameworks: JavaServer Faces

I zatwierdziłem je Finish.

Ctrl+Shift+N i z kategorii UML wybrałem Java-Platform Model.


Opis tego typu projektu - Java-Platform Model - bardzo wymyślny:

Creates a platform-dependent modeling project in the system with empty containers for your model and elements. As you create and populate your model, Java modeling (business) rules are applied to the model.
Nic nie zrozumiałem!

Wciskam Next > i jako w polu Project Name wpisuję PowitanieWebAppUML. Finish.

Wybieram Class Diagram o nazwie PowitanieClassDiagram.


Finish.

Pojawi się edytor UML z diagramem klas. Po prawej stronie pojawi się paleta elementów UML.


Utworzyłem klasę Powitanie z mapą pozdrowień (zaznaczam element Class i przeciągam do edytora. Enter i podaję nazwę Powitanie). Tworzę pakiet pl.jaceklaskowski.jsf.uml z użyciem elementu Package. Ciekawym podejściem jest umożliwienie stworzenia wielu elementów danego typu (na przykład pakietów) i nadawanie im nazw przez Enter, czyli lewy przycisk myszy, Enter, wpisuję nazwę i ponownie Enter, i tak z kolejnymi elementami.

Definiuję atrybut Map<String, String> powitania = new HashMap<String, String>() i kasuję operację setPowitania.

Dodałem operację (metodę) addPowitanie(String jezyk, String powitanie)


Prawym przyciskiem na projekcie PowitanieWebAppUML wybieram menu Generate Code, gdzie jako Target Project podaję PowitanieWebApp. Zatwierdzam OK.

Projekt PowitanieWebApp zostanie oznaczony jako błędny (czerwona ikona na nazwie projektu), gdyż Map oraz HashMap są podane bez ich pakietów. Otwieram Powitanie.java, Ctrl+Shift+I i Enter. Po chwili NetBeans rozpozna zmiany i zniesie komunikat błędu. Jest czysto.

Dodaję ciało do konstruktora i metody addPowitanie. Ostatecznie klasa prezentuje się następująco:
 package pl.jaceklaskowski.jsf.uml;

import java.util.HashMap;
import java.util.Map;


//
// #[regen=yes,id=DCE.0C3BC662-D50C-31DA-16B7-26AFB9E13435]
//

public class Powitanie {

//
// #[regen=yes,id=DCE.20E0A115-46D3-0681-089A-41017816B6C6]
//

private Map powitania = new HashMap();

//
// #[regen=yes,id=DCE.5585E6DF-BAC1-C496-0665-DEC6A9BA153E]
//

public Powitanie () {
// zdefiniuj kilka powitań
powitania.put("en", "Hi!");
powitania.put("pl", "Cześć!");
powitania.put("de", "MoinMoin!");
powitania.put("ru", "Zdrastwujcie!");
}

//
// #[regen=yes,id=DCE.5AB5D39E-7AF1-D127-881C-3F9F766AE597]
//

public void addPowitanie (String jezyk, String powitanie) {
powitania.put(jezyk, powitanie);
}

//
// #[regen=yes,regenBody=yes,id=DCE.383F3A78-B7A8-812E-E5D4-B13087852CFE]
//

public Map getPowitania () {
return powitania;
}

}
Owe znaczniki <editor-fold> są związane z powiązaniem klasy z diagramem UML.

Pora na zdefiniowanie nowopowstałej klasy jako ziarna zarządzanego JSF. Tutaj niestety jedynym sposobem jest edycja pliku konfiguracyjnego aplikacji jsf - faces-config.xml. Ale moment! Niespodzianka! Możliwość definiowania ziaren jest możliwa poprzez Add Managed Bean... w widoku XML edytora faces-config.xml.


Tego wcześniej nie wiedziałem, ani nie napotkałem w artykułach netbeansowych. Choćby dlatego warto było zacząć naukę UML (i już mi się będzie UML w wykonaniu NetBeans mile kojarzył ;-))

Definiuję nowe ziarno powitanie, wybieram klasę z listy Browse... o zasięgu session.


Zatwierdzam przyciskiem Add.

Plik faces-config.xml prezentuje się następująco:
 <?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<managed-bean>
<managed-bean-name>powitanie</managed-bean-name>
<managed-bean-class>pl.jaceklaskowski.jsf.uml.Powitanie</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
Zmieniam stronę welcomeJSF.jsp dodając wywołanie ziarna:
 <%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Pozdrowienia</title>
</head>
<body>
<f:view>
Powitanie w języku <b>${pageContext.request.locale.language}</b> brzmi...
<h1><h:outputText value="#{powitanie.powitania[request.locale.language]}" /></h1>
</f:view>
</body>
</html>
Zmiana polega na wywołaniu metody getPowitania() ziarna powitanie zwracającej mapę, której kluczem jest język, który w JSF uzyskuje się poprzez request.locale.language, podczas gdy w JSP za pomocą pageContext.request.locale.language (to są dwa różne języki EL rozróżniane przez znaki # oraz $, odpowiednio).

Najwyższy czas przekonać się o działaniu mojej aplikacji webowej. Wciskam F6 i po chwili moim oczom ukazuje się...


Zmiana języka na pl (w Firefox - Tools > Options... > Advanced > General > Languages) i F5 (odświeżenie strony) i


A na ru (rosyjski)


Działa! Niemiecki pozostawiam jako ćwiczenie domowe.

Czy to zademonstrowało UMLa w wykonaniu NetBeans 6.1 w pełni? Wątpię. Kolejnym razem jednak znowu coś spróbuję i może w ten sposób poznam UML lepiej. Może nawet zacznę go regularnie używać?

Na zakończenie sprawdzę jeszcze co udostępnia NetBeans w demonstracyjnych aplikacjach - Ctrl+Shift+N, Samples > UML i jest jedynie UML Bank App Sample.


Niewiele. Na szczęście przykład działa, chociaż odpowiada temu, co właśnie przeczytałem. Potrzebuję artykułu o tworzeniu aplikacji webowych z użyciem UML. Choćby niewielki, który wskaże, czy w ogóle ma to sens. Wciąż poszukuję...

I pytanie konkursowe (w trwającym konkursie bez nagród): Co to jest UML?