Blog do projektu Open Source JavaHotel

wtorek, 17 kwietnia 2012

Byliśmy na koncercie

W dniu 6 kwietnia 2012 byliśmy na finałowym koncercie XVI Wielkanocnego Koncertu Beethovenowskiego, muzyka się nam podobała, ale reżyseria koncertu mniej.
Męczeństwo Świętego Sebastiana Claude'a Debussego  to rzadko wykonywana muzyka tego kompozytora, według zapewnień organizatorów było to pierwsze wykonanie w Polsce. Pierwotnie była skomponowana jako ilustracja muzyczna do sztuki Gabriele d'Annunzia. Sama sztuka jednak nie zdobyła sobie powodzenia i została natychmiast zapomniana. Natomiast muzyka na szczęście nie podzieliła losu sztuki. Oczywiście nie ma możliwości odtwarzania muzyki tak jak to zamierzał kompozytor, najczęściej jest wykonywania jako czteroczęściowa suita.
Ale co się nam nie podobało ? Było złym pomysłem wprowadzenie narracji przed rozpoczęciem każdego aktu, nawet jeśli wygłaszającym tekst był znakomity aktor Andrzej Seweryn. To nie są porywające czy niezwykłe teksty, można było je opuścić bez żadnego zubożenia koncertu.  Natomiast rozbijało to ciągłość i utrudniało odbiór muzyki. A wielka szkoda, bo muzyka jest bardzo efektowna, właśnie za to tak lubimy Debussiego. Bardzo zmienna, dynamiczna, bogato zinstrumentalizowana, z dużą rolą instrumentów dętych. Dodatkowo w bardzo dobrym wykonawstwie Sinfonii Varsovii, Chóru Filharmonii Narodowej, solistek (chociaż tutaj miały mniejsze pole do popisu), zaś całością bardzo dobrze dyrygował Sylvain Cambreling.
Na pewno bardzo dobrym pomysłem organizatorów było sięgnięcie po mniej znany, ale także znakomity repertuar. Ale wielka szkoda, że efekt został trochę zniweczony przez nieprzemyślaną koncepcją realizatorską.


poniedziałek, 16 kwietnia 2012

Google App Engine and getLocalizedMessage

Problem
I found a nasty problem in Google App Engine - look at this JSP code.
Sometimes it is very useful to get localized message in JSP scriplet. For instance,  to use it as a parameter to other java method or as a attribute value to a JSP tag.
<%
  String hello = LocaleSupport.getLocalizedMessage(pageContext, "Hello");
  Object params[] = { "John" };
  String helloJohn = LocaleSupport.getLocalizedMessage(pageContext, "HelloName",params);  
%>
But the code above does not work in Google App Engine (run). What is worse - it works in development mode but after deploying to Google App Engine one gets into trouble. So it is not easy to recognize this issue, particularly in a larger project.

/notworkinghello.jsp
java.lang.NoClassDefFoundError: org/apache/taglibs/standard/tag/common/fmt/BundleSupport
 at javax.servlet.jsp.jstl.fmt.LocaleSupport.getLocalizedMessage(LocaleSupport.java:143)
 at javax.servlet.jsp.jstl.fmt.LocaleSupport.getLocalizedMessage(LocaleSupport.java:63)
 at org.apache.jsp.notworkinghello_jsp._jspService(notworkinghello_jsp.java:72)
......
What is more interesting, JSTL Code fmt:message tag is working as expected.
Solution
The only solution I found is to use BundleSupport class directly and create custom getMessage method.
It looks as below:
import java.text.MessageFormat;
import java.util.ResourceBundle;

import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.jstl.fmt.LocalizationContext;

import org.apache.taglibs.standard.tag.common.fmt.BundleSupport;

public class GetLocalizedMessage {

 /**
  * Replacement for LocaleSupport.getLocalizedMessage method in JSP pages
  * Before calling set fmt:setLocale and fmt: setBundle
  */
 
 private GetLocalizedMessage() {

 }

 /**
  * Gets localized message (also MessageFormated) from I18N bundle
  * @param pageContext PageContext
  * @param key Message key
  * @param params List of parameters for MessageFormat (if exists) 
  * @return localized message
  */
 public static String getMessage(PageContext pageContext, String key,
   String... params) {

  LocalizationContext loca = BundleSupport.getLocalizationContext(
    pageContext);
  ResourceBundle bundle = loca.getResourceBundle();
  String message = bundle.getString(key);
  if (params.length == 0) {
   return message;
  }
  String mess = MessageFormat.format(message, params);
  return mess;
 }

}

Then instead of getLocalizedMessage method from LocaleSupport class use method above directly - as source below.
<%
  String hello = GetLocalizedMessage.getMessage(pageContext, "Hello");
  String helloJohn = GetLocalizedMessage.getMessage(pageContext, "HelloName","John");
%>
The rest of the JSP page can be left without change. Finally the JSP page works as expected also in Google App Engine.
Source code 
The whole project is available here.

sobota, 7 kwietnia 2012

Byliśmy na koncercie

W dniu 1 kwietnia 2012 roku byliśmy na koncercie w ramach XVI Festiwalu Beethovenowskiego, podobało nam się bardzo. Sam koncert odbył się w pięknym wnętrzu Sali Wielkiej Zamku Królewskiego.
Hołdem złożonym dla patrona festiwalu było wykonanie Sonaty na wiolonczelę i fortepian D-dur op. 102 nr 2, ale to na pewno nie Beethoven było głównym bohaterem tego koncertu. Sam koncert wypełniła muzyka kompozytorów XX wiecznych, zaś zgodnie z intencją organizatorów koncertu motywem łączącym utwory była wojna i związki z wojną.
Ogromnie nam się podobał wykonany na koniec "Kwartet na koniec czasu" Oliviera Messiaena, tym bardziej że muzyka tego kompozytora nie tak często gości w Warszawie. Prawykonanie utworu odbyło się w okolicznościach niezwykłych, gdy kompozytor przebywał w obozie jenieckim w Zgorzelcu. Nadzorcy więzienni okazali się być miłośnikami muzyki, którzy umożliwili kompozytorowi pracę na utworem, zaś dobór instrumentów (klarnet, skrzypce, wiolonczela i fortepian na którym grał kompozytor) był wymuszony faktem, że akurat muzycy o takich specjalnościach odnaleźli się wśród współwięźniów. Poszczególne części utworu wykonywane są w różnym składzie, jedna część jest w całości wykonywana przez klarnet solo, są także części wykonywane przez same skrzypce z akompaniamentem fortepianu oraz podobnie wiolonczelę. Nie jestem specjalistą, ale wykonywać ten utwór muszą muzycy będący zarówno znakomitymi solistami jak i kameralistami.
Prawykonanie odbyło się 15 stycznia 1941 roku. Pamięć kompozytora po latach mnożyła liczbę więźniów będących słuchaczami czy ogrom trudności wykonawczych spowodowane kiepskim stanem instrumentów na których przyszło grać, ale utwór który powstał jest niezwykły i bardzo piękny, świadectwo czasów w jakich powstał, a także głębokiej wiary kompozytora.
Historia żołnierza Igora Strawińskiego to utwór bardzo znany, popularny i chętnie wykonywany. Zazwyczaj jest wykonywany w wersji koncertowej, często z dodaniem baletu i narracji. Ale, jak się przekonaliśmy, nic nie traci, a nawet zyskuje także w wersji kameralnej na klarnet, skrzypce i fortepian. A już na pewno, gdy wykonawcami są znakomici soliści, jak Kaja Danczowska na skrzypcach czy Michel Lethiec na klarnecie.
Dwa utwory Szostakowicza:  II Trio fortepianowe e-moll op. 67 oraz VIII Kwartet smyczkowy c-moll op. 110 także mają związek z wojną. Pierwszy został napisany w 1944, zaś po raz pierwszy wykonany w tym samym roku w Leningradzie , mieście niezwykle ciężko doświadczonym przez wojnę. Zaś drugi został napisany w 1960 roku i miał być muzyką do filmu o zbombardowaniu Drezna w 1945 roku. To muzyka bardzo efektowna, miejscami bardzo dynamiczna i głośna, miejscami wyciszona i spokojna. Pasjonujące było zwłaszcza obserwowanie wykonania pierwszej części II Tria fortepianowego, który zaczyna wiolonczela grająca solo.
Cały koncert trwał prawie cztery godziny, to był wspaniały wieczór. Jedyne co bym zmienił to dodanie jednak partii narracyjnej do "Historii żołnierza" Strawińskiego, bez tego rozumienie muzyki trochę traciło.  Wydłużyło by to tę cześć koncertu, ale można by zrezygnować z jednego z utworów Szostakowicza, zwłaszcza, że oba utwory są stylistycznie bardzo podobne, a nawet dzielą ze sobą ten sam temat muzyczny.

niedziela, 1 kwietnia 2012

Search and filter enhancement

General

I added simple enhancement to search and filter interface.
It is not easy to design a good search and filter mechanism. On one hand it should be powerful enough to allow the user to find what he/she needs, on the other it cannot be complicated because it would be rejected. So how to combine together effectiveness and usability. I don't mean that I'm in a possession of the magic formula but to my thinking the most convenient way is the "from - to" or "equal to" paradigm. Something like: "find all persons of age from 20 to 30" or "find all persons living in .. eg. find all persons whose place of residence is equal to ..".
Another approach to make the filter/searching mechanism as simple as possible is avoiding any additional improvement or modifiers (check or radio boxes) something like "in case of something cannot be found try something else" because it makes all stuff very complicated and finally it is not obvious what is looked for and what is found.
So I ended up with simple "from value" - "to value" schema without any buetyfiers.




















The formula is a simple as follows:
  • If neither "from" nor "to" value is entered then this field (attribute) is ignored during searching.
  • If only "from" value is enter ("to" remains empty) then mechanism picks up rows equal to the "to" value.
  • If both "from" and "to" values are entered then all rows between (inclusive) them are selected.
  • If only "to" value is entered ("from" remains empty) then all rows less or equal to the "to" value are selected.
  • All "from" - "to"  lines are participating in the query in "and" manner. For instance: if filter for "Symbol" attribute is used (meaning that either "from" or "to" value is not empty) and the same for "Nazwa" attribute then all rows passing both tests are selected.

To my experience that simple and intuitive mechanism is well appreciated by most users and enough in  most cases. Of course it is possible to enrich this schema by adding a lot of checboxes like ("and", "or", "equal", "less then") but it makes all stuff more complicated and does not bring many more value.

But, unfortunately, I was unable to keep to it any longer. Very often user needs to find something like "find all rows equal or greater than value" and this mechanism does not allow it. It is possible to put into "to" field very big value but it is artificial.
So I ended up with adding additional check box(GUI layout needs some improvements) :


The meaning of this additional check box is as follows.
If "from" value is entered and "to" value is empty then
  • If checkbox is checked then select all rows equal to the "from" value (default).
  • If check box is unchecked than find all rows equal or greater then "from" value.
 I'm not very happy with that because I had to break a rule (no single checkbox at all) but I was unable to find any other solution.

Demo version
Demo version is available here. The source code is available here. The data is persisted by means of Google App Engine for Java (JPA). The code for persistence layer and entity bean is also available.