sobota, 31 maja 2008

Zagadka w Javie

Dzisiaj mam zagadkę dla osób piszących w Javie :)
Wszyscy wiemy że:
x += i;
jest tym samym co:
x = x + i;

Musze wyprowadzić wiele osób z błędu - tak NIE jest!
Zadaniem jest podanie przykładu na to :) (w języku Java)

good luck :)

Symulator lotu w GoogleEarth

Programiści z Google ukryli w ich produkcie GoogleEarth symulator lotu. Aktywować go można po wybraniu kombinacji ctrl+alt+a.

Opcji może nie ma zbyt wiele ale za to polecieć możemy gdziekolwiek chcemy :)
Do wyboru mamy dwa rodzaje samolotów: F16 oraz SR22. Startować możemy z wybranego lotnika (dostępnych 27) lub zacząć latać z aktualnego widoku.

Cała klawiszologia dostępna jest na stronie Google.

ps. bez joysticka nie da się tym sterować ;/

piątek, 30 maja 2008

Blokada plików w PHP

Dość często zdarza się, że trzymamy jakieś dane w pliku. Np. wiadomości z shoutboxa lub listę osób które podpisały petycje. Ważną rzeczą jest aby podczas zapisu zakładane były blokady dostępu. Sprawa jest dość oczywista - nie możemy dopuścić aby w jednym momencie dwa działające skrypty modyfikowały jeden plik, prowadzi to do oczywistej utraty danych. Aby temu zapobiegać należy zakładać na plik blokady podczas operacji zapisu.
W PHP dostępne są następujące poziomy blokad:
LOCK_SH = 1 - gdy odczytujemy z pliku
LOCK_EX = 2 - gdy zapisujemy do pliku
LOCK_UN = 3 - zdjęcie blokady
Jeśli chcemy założyć blokadę na zapis to wcześniej wszystkie inne blokady muszą być zdjęte. Aby założyć blokadę na odczyt wystarczy aby nie była na nim założona blokada na zapis.
Blokady zakłada się za pomocą funkcji flock posiadającej dwa parametry:
$handle - uchwyt na plik
$operation - typ blokady

Przykład:
$file = fopen('example.txt' 'r+');
flock($file, LOCK_EX);
fwrite($file, $example_data);
flock($file, LOCK_UN);
fclose($file)

taki kod gwarantuje nam poprawny zapis do pliku. W przypadku gdy skrypt zażąda dostępu do pliku, który jest aktualnie zablokowany to skrypt jest wstrzymywany do czasu zwolnienia blokady i uzyskania dostępu do pliku.

Istnieje także możliwość sprawdzenia czy plik jest zablokowany. Aby tego dokonać należy dodać 4 do kodu blokady którą sprawdzamy. Wywołanie flock z takim parametrem jako operacja zwróci false jest plik jest pod działaniem blokady lub true jeśli nie jest.
Np.
$file1 = fopen("somefile.txt", "r+");
$file2 = fopen("somefile.txt", "r+");

flock($file1, LOCK_EX);

if( flock($file2, LOCK_EX + 4) )
{
echo("File is not locked");
}else{
echo("File is locked");
}

flock($file1, LOCK_UN);

Wykonanie skryptu spowoduje wyświetlenie komunikatu "File is locked".

Ważna uwaga - NIE łaczymy blokad w taki sposób:
flock($file, LOCK_EX and LOCK_SH); // ŹLE !!
flock($file, LOCK_EX or LOCK_SH); // ŹLE !!
flock($file, LOCK_EX + LOCK_SH); // ŹLE !!

Blokady zakładamy jeden po drugim, NIGDY ich nie łączymy! Tak jest poprawnie:
flock($file, LOCK_EX); 
flock($file, LOCK_SH); // dobrze

Jeszcze dwie uwagi na koniec:
- sprawdzanie czy na plik została założona blokada nie działa pod Windowsem (;/).
- blokady nie działają na systemach plików NFS, FAT.

Wiedza może rzadko kiedy przydatna, ale z pewnością bezcenna podczas pisania biblioteki do parsowania własnego formatu pliku ;-)
Zapraszam też do poczytania komentarzy na stronie dokumentacji flock gdzie znajdziecie wiele przydatnych rozwiązań związanych z tą funkcją.

Polska na Euro2008

Ktoś zrobił ładny filmik o polskiej reprezentacji z głosami i dźwiękiem z filmu "300" - dobra motywacja :-)



Hmmm tylko, że cytat "Spartan's, tonight we dine in hell" chyba trochę źle wróży :P

ps. POLSKA GOLA !!!!

Fontanna Bellagio w Las Vegas

Robi WRAŻENIE! Chciałbym kiedyś zobaczyć na żywo taki pokaz:)

Bellagio Fountains from michael john on Vimeo.

środa, 28 maja 2008

Lokalizacja wyjątków w Javie

Podczas pisania dużych aplikacji konieczne jest często stworzenie różnych wersji językowych. Dzisiejszego dnia zajmiemy się lokalizacją wyjątków, aby ładnie i czytelnie informowały użytkowników z całego świata, że nasza aplikacją się rozkraczyła :)))

Zaczynamy od stworzenia klasy przechowującej wiadomość wyjątku. Do tego zaprzęgamy klasę ListResourceBundle którą bardzo ładnie przechowuje nam pary klucz-wartość.
Najpierw stworzymy klasę przechowującą wiadomość która zostanie wyświetlona gdy nie zostanie znaleziona inna dla konkretnego języka.

ExceptionResourceBundle.java:

import java.util.ListResourceBundle;

public class ExceptionResourceBundle extends ListResourceBundle {

private static final Object[][] contents = { { "criticalException",
"Wystąpił błąd krytyczny" } };

public Object[][] getContents() {
return contents;
}
}

Ok, teraz można stworzyć jakieś lokalizacje.
Wersja językowa aplikacji wybierana jest poprzez kombinację symbolu określającego język oraz kraj. Np
de - język niemiecki
en-US - język angieski, kraj USA
itp. takie kody są normami ISO.
Zgodnie z tymi kodami wybierana jest klasa przechowująca wiadomość w danym języku. Np dla języka francuskiego bedzie to [nazwa_klasy]_fr, dla angielskiego USA [nazwa_klasy]_en_US (w Javie nie można używać znaku '-' w nazwie klasy wiec zastępujemy go przez '_').
No to zróbmy wersje wyjątku w języku angielskim dla kraju USA...

ExceptionResourceBundle_en_US.java:

public class ExceptionResourceBundle_en_US extends ExceptionResourceBundle {
private static final Object [][] contents = {
{"criticalException", "Critical error!"}
};
public Object [][] getContents(){ return contents; }
}

wersja francuskojęzyczna...

ExceptionResourceBundle_fr.java:

public class ExceptionResourceBundle_fr extends ExceptionResourceBundle{
private static final Object [][] contents = {
{"criticalException", "Il y'a quelque chose qui cloche!"}
};
public Object [][] getContents(){ return contents; }
}

Dziedziczymy po ExceptionResourceBundle aby uniknąć powtarzania wpisów których nie lokalizujemy.
Skoro mamy zlokalizowane komunikaty to trzeba by stworzyć zlokalizowany wyjątek:)
Kody krajów i języków przechowuje klasa Locale. Wyboru odpowiedniej klasy ze zlokalizowaną wiadomością dokonuje metoda ReosourceBundle.getBundle(String baseName, Locale locale). Zwraca ona obiekt najbardziej pasujący dla danych kodów zawartych w obiekcie locale.
No to piszemy naszą klasę wyjątku. Główne znaczenie ma tutaj przeciążona metoda getLocalizedMessage().

LocalizedException.java:

import java.util.Locale;
import java.util.ResourceBundle;

public class LocalizedException extends Exception {
public static final String DEFAULT_MESSAGE_KEY = "criticalException";
private String localeMessageKey = DEFAULT_MESSAGE_KEY;
private String languageCode;
private String countryCode;

public LocalizedException(String message) {
super(message);
}

public LocalizedException(Throwable cause, String messageKey) {
super(cause);
if (isValidString(messageKey)) {
localeMessageKey = messageKey;
}
}

public LocalizedException(String defaultMessage, Throwable cause,
String messageKey) {
super(defaultMessage, cause);
if (isValidString(messageKey)) {
localeMessageKey = messageKey;
}
}

public LocalizedException(String defaultMessage, String messageKey,
String language, String country) {
super(defaultMessage);
if (isValidString(messageKey)) {
localeMessageKey = messageKey;
}
if (isValidString(country)) {
countryCode = country;
}
if (isValidString(language)) {
languageCode = language;
}
}

public void setLocaleMessageKey(String messageKey) {
if (isValidString(messageKey)) {
localeMessageKey = messageKey;
}
}

public String getLocaleMessageKey() {
return localeMessageKey;
}

public String getLocalizedMessage() {
ResourceBundle rb = null;
Locale locale = getLocale();
rb = ResourceBundle.getBundle("ExceptionResourceBundle", locale);
return rb.getString(localeMessageKey);
}

private Locale getLocale() {
Locale locale = Locale.getDefault();
if ((languageCode != null) && (countryCode != null)) {
locale = new Locale(languageCode, countryCode);
} else if (languageCode != null) {
locale = new Locale(languageCode);
}
return locale;
}

private boolean isValidString(String input) {
return (input != null) && (!input.equals(""));
}
}

I to wszystko :) Teraz napiszmy krótki programik testujący nasz wyjątek.

LocalizedExceptionTest.java:

public class LocalizedExceptionTest{
public static void main(String [] args){
LocalizedExceptionTest application = new LocalizedExceptionTest();
application.testLocalizedException("Angielski - USA:", "en", "US");
application.testLocalizedException("Domyślny:", null, null);
application.testLocalizedException("Francuski:", "fr", "");
application.testLocalizedException("Włoski:", "it", "");
}

public void testLocalizedException(String message, String language, String country){
try{
throw new LocalizedException("Just testing!", "", language, country);
}
catch (LocalizedException exc){
System.err.println(message + " " + exc.getLocalizedMessage());
}
}
}

Po uruchomieniu konsola powinna nam wypluć:
Angielski - USA: Critical error!
Domyślny: Wystąpił błąd krytyczny
Francuski: Il y'a quelque chose qui cloche!
Włoski: Wystąpił błąd krytyczny

Dla włoskiego dostaliśmy wiadomość po polsku gdyż nie została zlokalizowana klasa odpowiedzialna za ten język, dlatego użyto wartości domyślnej.

Mam nadzieje, że kiedyś komuś się przyda ten art ;-)
Pozdrawiam i zapraszam do komentowania i zadawania pytań w razie niejasności.

PHP 5.3 = PHP6 beta ?

Twórcy PHP postanowili wprowadzić kilka nowości, które miały pojawić się dopiero w PHP6 już w kolejnej wersji PHP5 - 5.3.
Lista nowości:
- przestrzenie nazw (!)
- słowo kluczowe use do przestrzeni nazw
- aliasy do przestrzeni nazw
- stałe w obrębie klasy
- późne statyczne wiązanie
- obsługa przestrzeni nazw w funkcji magicznej __autoload
- funkcja magiczna __callstatic
- natywna obsługa MySQL
- dodatkowe funkcje dla OpenSSL
- nowe poziomy błędów i poprawki w aktualnych
- profile XSLT
i wiele innych ;-)

szczegóły i przykłady : sitepoint.com

Jak dla mnie wypas:) Jeszcze gdyby zrobili nareszcie porządna bibliotekę standardową....
Nowa wersja php powinna pojawić się do końca czerwca.

poniedziałek, 26 maja 2008

Potężny Indeksowy Wyświetlacz Oknowy

Z okazji PIWO 2 we Wrocławiu organizatorzy stworzyli wyświetlacz z okien akademika. Efekt robi wrażenie:


Więcej: OSnews.pl

czwartek, 22 maja 2008

aloha blip.pl !



Nuda goniła nudę, więc stwierdziłem, że czas sobie dodać jakiegoś nowego gadzeta do zabawy. Czytając bloga teodora zwróciłem (tym razem większą) uwagę na wigeta z blip.pl z jego wpisami - a co mi tam... też se założę ;-)

Blip.pl jest polską wersją serwisu twitter.com. Trudno mi określić precyzyjnie do czego jest Blip. Jednym zdaniem to by było: serwis do informowania znajomych o wszystkim gdziekolwiek się jest. Głównie wysyła się wiadomości o tym co się aktualnie robi i gdzie się znajduje. No ale pisać można wszystko od stanu pogody za oknem po stan naszych rozważań na temat realizmu. Żeby określić dokładnie czym jest blip powstał nawet specjalny tag. Więcej na: Blipcast.pl.

Najlepiej opisze to prezentacja:

(żródło: Blip.pl)

Więcej technicznych szczegółów w prezentacji Zbigniewa Sobieckiego:

(źródło: bootstrap.pl)

Tak więc możliwości mamy dość spore (mmsy, smsy, wiadomości głosowe...), mam nadzieje, że zainteresowało, bo nie mam zbyt wielu znajomych ;P

Co do otrzymywania wiadomości to chciałbym jeszcze dodać ciekawą możliwość związaną z tagami. Same tagi służą do nadania kategorii wpisowi, robi się to poprzez komendę #[nazwa tagu] w treści wiadomości. Dla każdego tagu w blipie można sobie ustawić powiadamianie. Dostępne są 3 opcje: brak powiadomień gdy pojawi się ten tag w wiadomości, powiadamianie tylko od znajomych, powiadamianie od wszystkich użytkowników. Dość ciekawe! Np. gdy ktoś jest zainteresowany bardzo #mjakmilosc ;P

Zapraszam także do serwisu blipspinki.pl który zajmuje się podziałem tematycznym wpisów (właśnie w oparciu o tagi), można dopisać się do grupy, lub stworzyć własną.

Serwis wg mnie dość ciekawy, przy większej liczbie znajomych może to być naprawdę fajna zabawa, dlatego zapraszam na blip.pl i na mojego bliploga :) Na tę chwilę trochę pusto ale dopiero co konto założyłem :)

Inne linki:
bliplog.pl - blog serwisu blip
blipgaleria.pl
bliplinki.pl
blipcast.pl - kanały blipa
Api serwisu blip
Twitter kontra blip, czyli jak to jest z tymi polskimi klonami

wtorek, 20 maja 2008

???? ???? ??? ??? ???

hmmm... pytanie brzmi:
dlaczego tutaj się nic konkretnego nie dzieje ?

Odpowiedzi prosimy nadsyłać w komentarzach, terminu brak ;-)

EDIT:
hmmm... widzę, że ludzie przestali tu zaglądać... czas coś tutaj rozkręcić ;-P

Kapitan Bomba :D:D:D


poniedziałek, 12 maja 2008

Internet! Internet! Łączy ludzi ludzi !

omg.... ciężko... bardzo ciężko...


piątek, 9 maja 2008

Fiat 126p - samochód jutra !

wersja cabrio wygrała :)