sobota, 16 maja 2009

Proste skalowanie aplikacji z Terracotta na Poznań Java User Group - 26.05.09r.

Zapraszam wszystkich na spotkanie Poznańskiej Grupy Użytkowników Javy poświęconemu oprogramowaniu wspomagającym skalowanie aplikacji w poziomie (ang. scaling out) o nazwie Terracotta. Prelegentem będzie Krzysztof Kliś programista w firmie BS Partner.

Oto krótkie streszczenie tego co będzie można usłyszeć na miejscu:
Terracotta jest oprogramowaniem open source, które pozwala na proste skalowanie w poziomie aplikacji działających na platformie Java, bez konieczności wykorzystywania dodatkowego kodu lub zewnętrznych baz danych. Efekt taki udało się uzyskać dzięki umieszczeniu całego mechanizmu klastrowania pomiędzy maszyną wirtualną Javy a warstwą aplikacji, dzięki czemu jest ona w praktyce całkowicie przezroczysta dla programisty. W trakcie prezentacji omówiona zostanie architektura Terracotty, przedstawione przykłady jej zastosowań (wraz z utworzeniem prostego projektu w Eclipse), a także współpraca z innymi technologiami opartymi na Javie (na przykładzie JRuby). Poruszone zagadnienia obejmą ponadto doświadczenia autora w pracy z Terracottą w kontekście wydajności, zagadnienia związane z licencją Terracotta Public License, jak również informacje na temat społeczności związanej z Terracottą.

Dodam jeszcze filmik z youtube mówiący co to jest Terracotta:


Miejsce i data spotkania:
Siedziba Cognifide - Aleje Wielkopolskie 4, Poznań
Wtorek 26.05.2009, godzina 18:00
Wymagana jest rejestracja pod adresem: www.oiola.com/e/382-spotkanie-poznan-jug-260509-terracota-krzysztof-klis/

Linki:
Web λ.0 - Functional programming for the Web - blog Krzysztofa Klisia

sobota, 9 maja 2009

Podstawowe komponenty w LWUIT #part 1/2

Skoro pierwsze spotkanie z biblioteką LightWeightUserInterfaceToolkit mamy już za sobą, chciałbym dziś przybliżyć podstawowe komponenty jakimi możemy się posługiwać aby wzbogacić UI naszej aplikacji mobilnej.

Hierarchia klas w LWUIT:


Component
To klasa bazowa dla wszystkich komponentów, tylko klasy które dziedziczą po niej mogą być wyświetlane na ekranie. W ogólności nie będziemy z niej korzystać chyba, że zaczniemy pisać własne komponenty to wtedy możemy się nią zainteresować;-)

Container
Kontener to obiekt który umożliwia przechowywanie w sobie wielu innych komponentów. W tym innych kontenerów które zawierają inne komponenty, możliwość zagnieżdżania jest praktycznie nieograniczona.
Komponenty które dodajemy do kontenera trafiają na listę wg której są później wyświetlane na ekranie, jeśli nie podamy indeksu na który ma on trafić to jest domyślnie umieszczany na ostatnim miejscu.

Form
Formularz jest klasą reprezentującą okna w programie. Składa się on z 3 części: paska tytułowego, zawartości okna oraz paska menu. Jak to wygląda przedstawia obrazek obok.
Jeśli chodzi o pasek tytułowy to wg mnie jest on trochę ograniczony ponieważ możemy na niego wrzucać tylko tekst, no ale gdyby było inaczej to może inaczej też by się nazywał ;P Zawartość okna to nasze pole gdzie wrzucamy jakiekolwiek komponenty potrzebujemy. Możemy je rozmieszczać za pomocą różnych układów (layouts) ale o nich znacznie więcej w innej części tutoriala.
Pasek menu zawiera pozycje pomocne przy sterowaniu aplikacją, jeśli jest ich więcej niż dwie to będzie nam się wyświetlać menu wyboru. Przycisku na tym pasku tworzy się poprzez dodanie do obiektu formularza obiektów typu Command.
Form udostępnia nam dwa konstruktory. Jeden jest bez bezparametrowy, a drugi posiada parametr typu String który jest tekstem na pasku tytułowym. Formularz wyświetlamy za pomocą metody Form.show();.
API tej klasy jest dość bogate i jego znajomość jest podstawą z którą trzeba się zapoznać.

Label
Label to po prostu komponent który wyświetla tekst i/lub obrazek. Należy pamiętać by używać go tylko w tym wypadku! Gdyby istniała potrzeba jakieś interaktywności to lepszym wyborem byłoby skorzystanie z klasy Button.
Dla zawartości etykiety możemy definiować wyrównania - domyślnym jest LEFT, ale poza nim jest jeszcze CENTER i RIGHT. Ponadto jeśli dodany jest zarówno tekst jak i obrazek to możemy wyrównać tekst względem obrazka mamy do dyspozycji pozycje: TOP, BOTTOM, LEFT, RIGHT. A wykonujemy to za pomocą metody: setTextPosition(Label.TOP);.
Może mały przykład:
Form form = new Form("Label in action!");
// utworzenie obrazka
Image image = Image.createImage("/picture.png");

Label label = new Label(image);
label.setText("Hello Label !!");
label.setAlignment(Label.CENTER);
label.setTextPosition(Label.BOTTOM);

// dodanie labela do formularza
form.addComponent(label);
// wyświetlenie
form.show();
Button
Przyciski wywołują dla nas jakieś akcje. Podobnie jak Label może składać się z ikony i teksty (przecież jest to klasa rozszerzająca Label^^). Do przycisku możemy podpiąć dwa rodzaje "słuchaczy" (nie lubię tej nazwy, zna ktoś może jakąś lepsza polską ?;), na aktywowanie (FocusListener) oraz akcje (ActionListener). Ponieważ drugi przypadek jest częstszy w użyciu to posłużę się nim jako przykładem. Może od razu podam przykład który wyjaśni działanie tego mechanizmu:
Button coolButton = new Button("Great button!");
coolButton.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent arg0) {
// instrukcje w tej metodzie zostaną wywołane po wciśnięciu przycisku
}
});
Można też utworzyć osobne klasy implementujące ten interfejs i podać je jako parametr. Zależy jakie kto rozwiązanie lubi i jak długa jest metoda obsługi zdarzenia.

RadioButton
To element dobrze nam znany chociażby z HTMLa. Jest to element który może posiadać dwa stany wybrany oraz nie wybrany. Stan taki może posiadać tylko jeden radio button w obrębie grupy o której za chwilę. Jeśli chodzi o zasady tworzenia oraz przypisywania obsługi zdarzeń to są one identyczne jak w przypadku przycisku.

ButtonGroup
Ta użyteczna klasa w sumie nie powinna zostać nazwana komponentem a bardziej takim zarządcą grupy komponentów. Jej funkcją jest grupowanie jakiegoś zbioru przycisków, żeby np. przypilnować, że został zaznaczony tylko jeden RadioButton.
Przykład działania:
// tworzenie przycisków
RadioButton radio1 = new RadioButton("RadioButton1");
radio1.setSelected(true); // niech jeden będzie zaznaczony domyślnie
RadioButton radio2 = new RadioButton("RadioButton2");
RadioButton radio3 = new RadioButton("RadioButton3");
RadioButton radio4 = new RadioButton("RadioButton4");

// tworzenie grupy oraz dodawanie do niej przycisków
ButtonGroup group = new ButtonGroup();
group.add(radio1);
group.add(radio2);
group.add(radio3);
group.add(radio4);

/**
* Jakieś operacje
*/

// pobranie indeksu który przycisk jest zaznaczony
int index = group.getSelectedIndex();
// pobranie zaznaczonego przycisku
RadioButton radioSelected = group.getRadioButton(index);
Gdy mamy indeks zaznaczonego przycisku to później można sobie zrobić jakiegoś switcha i wykonać odpowiednie akcje. Należy tylko pamiętać o tym by nie zmieniać kolejności ich dodawania do grupy, bo wg tego są one indeksowane.

To koniec części pierwszej o komponentach w LWUIT. W następnym wpisie z tej serii omówię CheckBox, ComboBox, TextArea oraz TabbedPane.

Zapraszam do komentowania !

_
Źródła obrazków oraz linki:
[1] https://lwuit.dev.java.net/
[2] http://lwuit.blogspot.com/

niedziela, 3 maja 2009

Pierwsze spotkanie sympatyków technik Agile w Poznaniu !

Na ostatnim spotkaniu Java User Group ogłoszono, że rozpoczyna się (oprócz Javowych) seria spotkań poświęcona technikom wytwarzania oprogramowania. Spotkania oprócz wystąpień mają w założeniu mieć także formę otwartej dyskusji. Pierwsze już 6 maja (czyli już w tę środę) w miejscu dobrze znanym czyli siedzibie Cognifide, przy ulicy Al. Wielkopolska 4 - godzina 18:00.

Będzie poświęcone sposobach prowadzenia projektu - metodyce Scrum. Prowadzącym spotkanie będzie pracownik firmy OpenX Andrzej Swędrzyński.
Oprócz wystąpienia spotkanie będzie także miało charakter organizacyjny - tematyka spotkań, terminy itp.

Zapraszam wszystkich !

ps. Zapraszam jeszcze na bloga AgileTuning.pl na którym można posłuchać bardzo ciekawych podcastów na ten temat.

piątek, 1 maja 2009

10 minut z biblioteką SAX - Simple API for XML

Przy okazji projektu z sieci komputerowych przyszło mi szukać biblioteki do parsowania XML, która będzie działać na wszystkich 3 platformach Java. Długo się nie zastanawiając wybrałem SAX. Miałem już dość męczenia się z jakimś kXML czy jakimś innym wytworem i wybrałem coś konkretnego. Jaki był tego koszt ? Moja aplikacja na komórkę będzie wymagać implementacji Java ME Web Service (JSR 172). No ale żałować nie będę, bo bez tego już chyba urządzeń mobilnych z Javą nie wprowadzają na rynek.

Ok, ale przejdźmy do zadania :) Trzeba parsować proste komunikaty XML o postaci:
<?xml version=”1.0” encoding=”utf-8”?>
<response value=”[odpowiedz]”>
<params>
<[klucz] value=”[wartość]”/>
<!-- inne parametry takiej postaci -->
</params>
</response>

Nie wygląda na trudne. Ale zobaczmy jak to się robi z użyciem SAX.
W pierwszej kolejności musimy utworzyć klasę handlera który będzie odpowiadać za obsługę poszczególnych elementów dokumentu XML. Klasa handlera musi dziedziczyć po klasie DefaultHandler, która umożliwia implementacje kilku bardzo przydatnych metod. Nasz handler będzie posiadać następujące:
- public void startElement(String uri, String localName, String qName, Attributes attribs) - metoda ta wywoływana jest gdy parser natrafi na znacznik otwierający
- public void endElement(String uri, String localName, String qName) - metoda ta zostanie wywołana po natrafieniu na znacznik zamykający
W tym miejscu dodam jeszcze notkę o metodzie characters chociaż jej nie będziemy używać jest dość istotna. Ma następującą sygnaturę:
- public void characters(char[] ch, int start, int lenght) - wywoływana jest gdy parser natrafi na tekst (tekstowa zawartość węzła)

A oto znaczenie poszczególnych parametrów:
uri - namespace uri
localName - lokalna nazwa znacznika (bez prefiksu)
qName - nazwa kwalifikowana znacznika (z prefiksem)
attribs - obiekt typu Attributes zawierający atrybuty danego znacznika
ch - tablica znaków
start - pozycja startowa w tablicy znaków
lenght - liczba znaków
To są absolutnie podstawowe metody które należy znać. Po więcej zapraszam do dokumentacji DeafultHadler.

Ok, to możemy przystąpić do implementacji klasy.
package com.blogspot.wookasz.saxexample;

import java.util.HashMap;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

class SAXMessageHandler extends DefaultHandler {
// flaga oznaczająca czy teraz wczytywane będą parametry
private boolean paramMode = false;
// parametry
private HashMap<String, String> params;
// wartość odpowiedzi w komunikacie
private String response;

public SAXMessageHandler() {
super();
this.params = new HashMap<String, String>();
}

@Override
public void startElement(String uri, String localName, String qName,
Attributes attribs) throws SAXException {
// jeśli natrafiono na węzeł z odpowiedzią
if (qName.equals("response") && !paramMode) {
response = attribs.getValue("value");
return;
}
// jeśli natrafiono na węzęł rozpoczynający parametry
if (qName.equals("params")) {
paramMode = true; // ustawiamy flagę że teraz będą parametry
return;
}

// jeśli ustawiona jest flaga parametrów
if (paramMode) {
// dodajemy parametr z wartością do mapy
params.put(qName, attribs.getValue("value"));
return;
}
}

@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// jeśli włączyony był tryb parametrów
// i nastrafiono na zamykający go znacznik
// to zmieniamy flegę
if (qName.equals("params")) {
paramMode = false;
}
}

public HashMap<String, String> getParams() {
return params;
}

public String getResponse() {
return response;
}
}

Komentarze w kodzie myślę wyjaśniają całkowicie działanie ;) Jakby co komentować!
Teraz czas na utworzenie parsera i zarejestrowanie handlera:)
To już tylko kilka linijek:
// utworzenie fabryki SAX
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
// utworzenie parsera
SAXParser parser = saxFactory.newSAXParser();
// utworzenie obiektu czytającego wiadomości XML
XMLReader reader = parser.getXMLReader();

// utworzenie naszego handlera
MessageSAXHandler xmlHandler = new SAXMessageHandler();
// oraz ustawienie go jako domyślnego dla obiektu czytającego
reader.setContentHandler(xmlHandler);

Teraz możemy poprzez metodę reader.parse(InputStram input) parsować wiadomości które do nas przychodzą. Należy zwrócić uwagę na to, że parametrem jest obiekt typu InputSource (dostępna jest jeszcze implementacja tej metody przyjmująca String - URI)! Jeśli mamy już całą wiadomość w pamięci to możemy to obejść w prosty sposób:
String xmlMsg = "[wiadomosc]";
InputStream streamXml = new ByteArrayInputStream(xmlMsg.getBytes()); // utworzenie strumienia bajtów z wiadomości
reader.parse(new InputSource(streamXml)); // parsowanie

Powinno działać :)

Jeszcze dodam uwagę co do implementacji tej biblioteki na platformie Java ME. JSR-172 trochę obcięło API i nie możemy utworzyć obiektu typu XMLReader. Na tej platformie parsowanie wygląda następująco:
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
SAXParser parser = saxFactory.newSAXParser();

SAXMessageHandler xmlHandler = new SAXMessageHandler();

parser.parse(new InputSource(streamXml), xmlHandler);

Oraz w klasie SAXMessageHandler należy zmienić typ zmiennej params na Hashmap.
To rozwiązanie powinno także działać w Java SE oraz Java EE ;-)

Mam nadzieję, że ten krótki tutorial komuś pomoże rozpocząć pracę z biblioteką SAX. Po więcej informacji zapraszam na stronę www.saxproject.org.