The power of shell – deleting old directories

Programowanie No Comments »

Supppose you have a number of directories created every month whose names contain some form of the creation date, e.g. FOO-201107011223.

Then you notice that what you actually need are only the directories created in the current month and you would like to get rid of the older ones periodically. Now the power of shell (and cron) comes to the rescue:

What we do here is list the contents of the directory containing the directories we are going to remove, then filter it by the date part contained in their names and – finally – pass the filtered list to the rm -rf command.

The fun part here is the date command and the magic behind the -d"1 month ago" switch. The date is then formatted to YYYYMM with the +%Y%m switch. No easier way of finding what the previous month was, isn’t it?

The last step is to make the above script execute periodically on a chosen basis. In my case I simply put it into /etc/cron.monthly. If there are no /etc/cron.something directories in your system, you will need to manually create a crontab entry with crontab -e.

Hacking the enum conversion in JSF 1.2_x

Java 1 Comment »

Suppose you have an enum and some of its methods are overridden by concrete enum values:

public enum SomeEnum {
    SOME_VALUE,
    OTHER_VALUE {
        @Override
        public boolean isDifferent() {
            return true;
        }
    };

    public boolean isDifferent() {
        return false;
    }
}

In the example a custom isDifferent() method is overridden, but it could as well be the existing toString().

If you attempt to use such an Enum (the OTHER_VALUE to be precise) within a view in a JSF application (using the reference implementation, haven’t tried MyFaces), you’re likely to get an exception like this:

javax.faces.convert.ConverterException: 'OTHER_VALUE' must be convertible
    to an enum from the enum, but no enum class provided.

After some debugging it turns out that enum values with non-empty body are not handled properly. If you have a look at the com.sun.faces.application.ApplicationImpl class, there’s a method

public Converter createConverter(Class targetClass) {
    ...
}

Normally, when JSF is looking for a converter for an enum without overridden values, the targetClass parameter is the concrete enum class (it should be SomeEnum in our case, but it actually is SomeEnum$Something). The method first tries to lookup a base type converter, but there’s none for SomeEnum$Something (that’s a surprise!). So, in the next attempt, it searches for interfaces implemented by the targetClass – but nothing here again. As a last resort, the method goes through a collection of targetClass’s superclasses. This time a superclass is found – it’s the SomeEnum – so the

protected Converter createConverterBasedOnClass(
            Class targetClass, Class baseClass) {
    ...
}

method is called with SomeEnum as the targetClass and SomeEnum$Something as the baseClass. Similar steps as above are now taken to find and appropriate converter for interfaces/superclasses of SomeEnum. As SomeEnum extends java.lang.Enum, the method is called recursively with null as the baseClass:

createConverterBasedOnClass(java.lang.Enum, null);

Finally, a matching converter is found for java.lang.Enum and an instance of javax.faces.convert.EnumConverter is created. Almost everything is fine, except for the fact that it gets the above null (passed as the baseClass above) injected as the target class in constructor parameter.

This causes the converter to throw the exception mentioned above when assuring that its target class is not null:

if (targetClass == null) {
    throw new ConverterException(MessageFactory.getMessage(
              context,
              ENUM_NO_CLASS_ID,
              value,
              MessageFactory.getLabel(context, component))
    );
}

Unlike the problem description, the solution seems to be quite simple. What we basically need to do is to handle the case when JSF is looking for a converter for an anonymous inner class of an enum and swap the classes in the call to createConverterBasedOnClass(). So if the tagetClass is our enum and the baseClass is its anonymous extension, we should call:

createConverterBasedOnClass(Enum.class, targetClass);

otherwise we shouldn’t change anything and call:

createConverterBasedOnClass(targetClass, baseClass);

To weave our solution into JSF we need to extend the com.sun.faces.application.ApplicationImpl class and override its createConverterBasedOnClass() method:

package org.kunicki.jsf;

import com.sun.faces.application.ApplicationImpl;

import javax.faces.convert.Converter;

/**
 * @author jacek@kunicki.org
 */
public class FixedEnumConverterApplicationImpl
    extends ApplicationImpl {

    @Override
    protected Converter createConverterBasedOnClass(
            Class targetClass, Class baseClass) {
        // if base class is an anonymous  inner class of an
        // enum, use Enum as the target class and targetClass
        // as the base class
        if (targetClass.isEnum()
                && baseClass.getName().contains(
                      targetClass.getName())
                && baseClass.getName().contains("$")) {
            return super.createConverterBasedOnClass(
                      Enum.class, targetClass);
        } else {
            return super.createConverterBasedOnClass(
                      targetClass, baseClass);
        }
    }
}

Now we need make JSF use the above implementation instead of the standard one. This is done by extending the com.sun.faces.application.ApplicationFactoryImpl and override the getApplication() method to simply return our FixedEnumConverterApplicationImpl:

package org.kunicki.jsf;

import com.sun.faces.application.ApplicationFactoryImpl;
import com.sun.faces.util.FacesLogger;

import javax.faces.application.Application;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author jacek@kunicki.org
 */
public class FixedEnumConverterApplicationFactoryImpl
    extends ApplicationFactoryImpl {

    private Application application;
    private static final Logger logger =
        FacesLogger.APPLICATION.getLogger();

    @Override
    public Application getApplication() {
        if (application == null) {
            application =
                new FixedEnumConverterApplicationImpl();
            if (logger.isLoggable(Level.FINE)) {
                logger.fine(MessageFormat.format(
                    "Created Application instance ''{0}''",
                    application)
                );
            }
        }

        return application;
    }
}

The final step is to register a custom application factory in faces-config.xml:


  
      org.kunicki.jsf.FixedEnumConverterApplicationFactoryImpl
  

So, this one worked for me. Of course you can simply avoid overriding methods in your enums or perhaps use MyFaces, which may not contain this bug. If you think this is a nice or bad solution, please leave a comment.

Lego Mindstorms and Android at GeeCON

Java, Lego Mindstorms, Programowanie No Comments »

Thanks everyone who attended my talk at GeeCON, especially considering the huge competition in the paralell sessions :)

If you’re interested in the slides, they’re available here (PDF, 5,6 MB).

Krótki film z prezentacji Lego Mindstorms NXT

Lego Mindstorms No Comments »

Poniżej krótki film pokazujący możliwości robota (operator: Adam, montaż: Michał)

Lego Mindstorms NXT – parametry techniczne

Lego Mindstorms 3 Comments »

Podczas mojej wczorajszej prezentacji na spotkaniu Warszawa JUG kilka osób pytało o parametry sprzętowe sterownika NXT. Oto one (źródło: http://en.wikipedia.org/wiki/Lego_Mindstorms_NXT#Technical_specifications):

  • 32-bitowy procesor AT91SAM7S256 (48 MHz, 256 kB pamięci flash, 64 kB RAM),
  • 8-bitowy mikrokontroler ATmega48 (4 MHz, 4 kB pamięci flash, 512 bajtów RAM),
  • kontroler Bluetooth CSR BlueCore 4 (26 MHz, 1 MB zewnętrznej pamięci flash, 47 kB RAM),
  • matrycowy wyświetlacz LCD (100×64 piksele),
  • port USB,
  • 4 porty wejściowe (do podłączania czujników),
  • 3 porty wyjściowe (do podłączania elementów wykonawczych, np. silników).

W zestawie dostajemy 519 klocków Technic oraz kilka elementów Bionicle (np. szczypce, które podczas prezentacji łapały piłeczki), a ponadto:

  • 3 identyczne silniki (serwomechanizmy) z wbudowanymi przekładniami redukcyjnymi oraz czujnikami położenia (czujniki te pozwalają odczytać położenie wału silnika z dokładnością do 1 (!) stopnia),
  • czujnik dotyku, rozróżniający, czy jest wciśnięty na stałe, czy tylko “kliknięty”,
  • czujnik światła, który może mierzyć natężenie światła z otoczenia lub natężenie światła odbitego od jakiegoś przedmiotu (wówczas korzysta on z wbudowanej diody LED do oświetlenia przedmiotu),
  • czujnik natężenia dźwięku (mierzy amplitudę),
  • ultradźwiękowy czujnik odległości (mierzący de facto czas, w jakim wysłana fala ultradźwiękowa wraca po odbiciu od przeszkody); maksymalna odległość, jaką czujnik może zmierzyć, to 233 cm, a dokładność pomiaru to 3 cm.

Ktoś (chyba Waldek Kot) pytał po prezentacji, czy Lego zamierza wypuścić następcę NXT. Okazuje się, że ten następca (NXT 2.0) został już zapowiedziany i ma pojawić się (w USA) w tym roku (źródło: http://www.robotsnob.com/archives/2009/02/at-last-lego-mindstorms-nxt-20.php).

Gdybyście mieli jeszcze jakieś pytania, zapraszam do umieszczania ich w komentarzach – postaram się odpowiedzieć.

Programowanie w J2ME pod MacOS X

Java, Programowanie 4 Comments »

Nie jest tak różowo, jakby się mogło wydawać, patrząc na liczbę dostępnych narzędzi. Tzn. mogłoby być różowo, gdybym korzystał z Windowsa lub Linuksa – wówczas recepta jest prosta i sprowadza się do instalacji jakiegoś IDE oraz Sun Java Wireless Toolkit for CLDC – zestawu narzędzi wspomagających programowanie w J2ME, zawierającego między innymi rozbudowany emulator urządzeń mobilnych (w dalszej części będę go nazywał WTK).

Niestety dla użytkowników systemu Apple praca z emulatorem Suna nie jest możliwa. Read the rest of this entry »

Czyim jesteś internautą?

Inne No Comments »

“INTERNAUCI TVN24.PL TRZYMALI RĘKĘ NA PULSIE”. “Wydarzenia związane z zamachami terrorystycznymi w Indiach działy się szybko. Nasi internauci byli jednak jeszcze szybsi.” (Kontakt TVN24)

Read the rest of this entry »

Kopiowanie listy

Java, Programowanie 3 Comments »

Można tak (przykład z życia):

List items = getSomeList();
Iterator it = items.iterator();
List itemIDs = new ArrayList();
do {
    if (!it.hasNext())
        break;
    Object o = it.next();
    if (items.contains(o))
        itemIDs.add(o);
} while(true);

A można też tak (ale to nie jest dobre rozwiązanie jeśli ktoś szacuje pracochłonność na podstawie liczby linii kodu):

List itemIDs = (List) ((ArrayList) items).clone();

(zakładając, że zależy nam na tym, aby stworzyć nową instancję listy). Warto pamiętać, że klonowanie kolekcji zwraca płytką kopię, czyli nową instancję kolekcji, która zawiera te same instancje elementów, co oryginalna kolekcja.

Poprawcie mnie, jeśli się mylę :)

Nakaz jazdy tyłem?

Inne 1 Comment »

Gdzieś w Łomiankach :)

Nakaz jazdy tyłem

Instalacja pakietu LaTeX Beamer

Inne 1 Comment »

Beamer jest klasą do LaTeXa, która umożliwia tworzenie ładnie wyglądających prezentacji. Nie jestem jakimś wielkim specem od LaTeXa, więc sposób instalacji Beamera nie był dla mnie do końca oczywisty – postanowiłem krótko opisać co i jak.
Read the rest of this entry »

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in