Archiwum na listopad, 2007

WampServer 2 to następca WAMP5 - zestawu: Apache, MySQL, PHP przygotowanego dla systemu Windows. Na pierwszy rzut oka nowa wersja nie różni się znacząco od poprzedniej. Mamy do dyspozycji to samo wygodne menu konfiguracyjne w systemowym trayu, stronę główną (choć ta została zmodyfikowana), phpMyAdmin i SQLiteManager.
Najważniejszą nowością jest umożliwienie szybkiej zmiany wersji Apache, MySQL i PHP, które można zainstalować niezależnie z paczek przygotowanych przez autorów WampServer. I tak: jednym kliknięciem myszy można zmienić np. Apache 1.3 na 2.2, MySQL 5.0.45 na 4.1.20 lub PHP 5.2.5 na 4.1.2. Nie muszę chyba szczególnie wyjaśniać dlaczego jest to takie przydatne.

News:
Dzisiaj światło dzienne ujrzała finalna wersja środowiska Visual Studio 2008. Dostępne są również darmowe edycje Express.

Więcej informacji na stronie: http://microsoft.com/vstudio/

Dzisiaj kilka słów chciałbym poświecić narzędziu, które wpadło mi w ręce kilka miesięcy temu - WinDev.
WinDev to w pełni zintegrowane środowisko programistyczne typu RAD tworzone przez francuską firmę PC SOFT. Obecnie dostępna wersja nosi numer XI, choć autorzy ogłaszają bliskie nadejście kolejnej edycji. Już po pierwszym uruchomieniu ogrom funkcjonalności rzuca na kolana. Warto jednak się z nich podnieść i przyjrzeć się bliżej możliwością. Oprogramowanie cechuje: tworzenie aplikacji wieloplatformowych (Windows, Linux, .NET, WebServices, J2EE) 32 i 64 bitowych (szkielet programu tworzony przy pomocy rozbudowanych kreatorów), wbudowane narzędzia CASE (z inżynierią wsteczną i generatorem dokumentacji), zintegrowana obsługa wielu baz danych, rozbudowany generator raportów, debugger, refactoring i wiele innych. Bardzo dobre wrażenie sprawia edytor, który podpowiada składnie poleceń (wraz z dokumentacją) w sposób niemalże doskonały. Język programowania (autorzy przedstawiają go jako piątek generacji i mają w tym trochę racji)- WLanguage - posiada łatwą, intuicyjną składnie i nie sprawia problemów nawet początkującym.
Czy to reklama produktu? Nie, raczej jego bardzo krótka charakterystyka. Ale żeby nie było zbyt pięknie - nie ma róży bez kolców. Tym najostrzej kującym jest cena (zbyt wysoka dla prywatnego użytkownika). Innym poważnym problemem jest stabilność, która jest na słabym poziomie, na tyle, że części funkcjonalności nie udało mi się przetestować.
WinDev zostępny jest w trzech edycjach: WinDev, WebDev (dla webmasterów) oraz WinDev Mobile (Pocket PC, …).

Lepszej jakości prezentacje dostępne są na stronie internetowej aplikacji.

To nie jest sponsorowany wpis.

Pod koniec ubiegłego miesiąca Sofware-Wydawnictwo rozpoczęło masową wyprzedaż archiwalnych numerów swoich pism. Dlaczego dopiero teraz o tym pisze? Po prostu wczoraj dostałem paczkę z 26 numerami: SDJ, phpsolutions oraz hackin9. Obejmują one zakres trzech pierwszych kwartałów bieżącego roku.
Wydawnictwo oferuje następujące zestawy (każdy zestaw 50zł):
- hakin9 od 6/2006 do 9/2007 (10 numerów)
- SDJ 12/2006 do 9/2007 (10 numerów)
- L+ 12/2006 do 9/2007 (10 numerów)
-.psd 6/2006 do 5/2007 (6 numerów)
- php 6/2006 do 5/2007 (6 numerów)
- psdextra 2 do 6
oraz w cenie 35zł:
- SDJE 20 do 25
- 6 dowolnych numerów L+ extra

Biorąc pod uwagę cenę pierwotną pojedynczego numeru (25-30zł), cena zestawu jest wyjątkowo kusząca. A tematyka opisywana nie dezaktualizuje się tak szybko jak w przypadku innych gazet komputerowych.

Dzisiaj przypadkowo natknąłem się na pewną niedogodność w kliencie poczty Thunderbird. Na jednym ze swoich kont używam kilku tożsamości. Dla konta głównego ustawiłem certyfikat S/MIME, a następnie próbowałem wysłać podpisanego cyfrowo e-maila korzystając z innej (nie głównej) tożsamości. Efekt - program Thunderbird nie potrafi odnaleźć właściwego certyfikatu.
W interfejsie ustawień poszczególnych tożsamości nie ma możliwości określenia certyfikatu, co jest ewidentną niedoróbką.
Trzeba zajrzeć pod przykrycie i dotrzeć do plików konfiguracyjnych - można to zrobić na dwa sposoby: “Opcje -> Zaawansowane -> Ogólne -> Edytor ustawień” lub wyszukując plik pref.js w katalogu profilu klienta pocztowego.

Procedura dodawania ceryfikatu S/MIME do tożsamości:
1. Szukamy w mail.server.server[ID] identyfikatora naszego serwera [ID]
2. Następnie w mail.account.account[ID].identities odszukujemy identyfikatory tożsamości [tID…]
3. Jeden z identyfikatorów tożsamości (przypuszczalnie pierwszy) mail.identity.id[tID] będzie miał przypisane dane certyfikatu S/MIME. Jeżeli dla innych tożsamości chcemy wykorzystać ten sam certyfikat, to dane te wystarczy skopiować, jeżeli inne, wówczas należy je właściwie określić.
4. Dla każdych innych tożsamości mail.identity.id[tID] należy utworzyć wpisy z odpowiednią zawartością:
mail.identity.idX.sign_mail
mail.identity.idX.signing_cert_name
mail.identity.idX.encryption_cert_name
mail.identity.idX.encryptionpolicy

Więcej informacji: http://forums.mozillazine.org/viewtopic.php?t=455694

JSON (JavaScript Object Notation) jest drugim, po XML, najpopularniejszym formatem przesyłania danych stosowanym w technologi AJAX. Niewątpliwą przewagą JSON’a nad XML’em jest jego natywne parsowanie po stronie klienta (funkcja JavaScriptu eval()). JSON pozwala również na proste serializowanie obiektów JavaScript.

Przykład składni JSON (przykład z Wikipedii na licencji GPL FDL):

{"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}
 

Analogiczny zapis w XML:

<menu id="file" value="File">
  <popup>
    <menuitem value="New" onclick="CreateNewDoc()" />
    <menuitem value="Open" onclick="OpenDoc()" />
    <menuitem value="Close" onclick="CloseDoc()" />
  </popup>
</menu>
 

Parsowanie JSON po stronie JavaScript sprowadza się do pojedynczej instrukcji:

var obiekt = eval(‘(’ + JSON + ‘)’);
 

Następnie do zmiennej obiekt można się odwoływać jak do zwykłego obiektu:

alert(obiekt.menu.id);  //zwróci "file"
alert(obiekt.menu.popup.menuitem[1].onclick); //zwróci "OpenDoc()"
 

Warto zaznaczyć, że JSON nie wymaga obecności znacznika głównego, tak więc zapis można jeszcze bardzie skrócić.

Pomimo iż według standardu JSON można przesyłać tylko dane (proste typy obsługiwane w JavaScript oraz obiekty JS), to jednak nie ma problemu z przesłaniem funkcji (w tym wypadku należy to rozumieć jako metodę obiektu):

{
  nazwa: "Funkcja",
  func: function(arg) { alert(arg); }
}
 

Przykład 1

Następnie funkcje wywołujemy:

var obiekt = eval(‘(’ + JSON + ‘)’);
obiekt.func(‘hello’);
 

Oczywiście możliwe jest traktowanie funkcji jako części obiektu (choć nie wchodzi to w skład standardu JSON!):

{
  nazwa: "Funkcja",
  func: function(arg) { alert(arg); },
  func2: function() { alert(this.nazwa); }
}
 

Wówczas:

obiekt.func2();
 

wyświetli napis “Funkcja”.

Przykład 2

Prezentacja wideo:

Zobacz prezentacje wideo

W przeciągu ostatniego roku można zauważyć zwiększenie zainteresowania formatem JSON. Do najbliższej specyfikacji języka Javascript zgłoszono dwie nowe metody klasy Object (klasy superbazowej) służące do serializacji i deserializacji obiektów. Wiele popularnych bibliotek i frameworków AJAX’owych korzysta z JSON jako podstawowego sposobu komunikacji.

PHP począwszy od wersji 5.2 posiada wsparcie do generowania i parsowania zapisu JSON (http://pl.php.net/json).

Przykład (zaczerpnięty z dokumentacji PHP):

< ?php
$arr = array (‘a’=>1,‘b’=>2,‘c’=>3,‘d’=>4,‘e’=>5);

echo json_encode($arr);
?>
 

wypisze:

{"a":1,"b":2,"c":3,"d":4,"e":5}
 

Natomiast:

< ?php
$json = ‘{"a":1,"b":2,"c":3,"d":4,"e":5}’;

var_dump(json_decode($json, true));
?>
 

zwróci tablicę:

array(5) {
    ["a"] => int(1)
    ["b"] => int(2)
    ["c"] => int(3)
    ["d"] => int(4)
    ["e"] => int(5)
}
 

Niezależnie od tych rozwiązań powstały zewnętrzne biblioteki, często o dużo większych możliwościach. Linki do tych rozwiązań można znaleźć na stronie: www.json.org.

Nie brakuje przy tym bibliotek dedykowanych językowi Java.

Dwie oficjalne można znaleźć na stronach: http://www.json.org/java/index.html oraz http://www.json.org/java/simple.txt (obydwie na otwartych i darmowych licencjach).

JSON.simple

W przypadku JSON.simple należy ściągnąć archiwum http://www.JSON.org/java/json_simple.zip
Wewnątrz znajduje się plik json_simple.jar, który należy dodać do projektu (umieszczając go w podkatalogu WEB-INF/lib/ projektu).

Od tej chwili możemy skorzystać z gotowych klas znajdujących się w pakiecie: org.json.simple.*. W szczególności wykorzystuje się dwie:

JSONArray
JSONObject
 

Zacznijmy od drugie. Można zrobić porównanie, że generuje ono jednopoziomową tablicę asocjacyjną:

import org.json.simple.JSONObject;

JSONObject obj=new JSONObject();
obj.put("name","foo");
obj.put("num",new Integer(100));
obj.put("balance",new Double(1000.21));
obj.put("is_vip",new Boolean(true));
obj.put("nickname",null);
System.out.print(obj);
 

Powyższy kod wygeneruje odpowiednio zakodowany i sformatowany ciąg JSON:

{"nickname":null,"num":100,"balance":1000.21,"is_vip":true,"name":"foo"}
 

JSONArray zachowuje się trochę inaczej. Tworzy, jak sama nazwa wskazuje, tablicę elementów (mogą być różnego typu!):

import org.json.simple.JSONArray;

JSONArray tab = new JSONArray();
tab.add("111");
tab.add(new Integer(222));
tab.add(new Double(333.33));
System.out.print(tab);
 

wypisze:

{["111",222,333.33]}
 

Obiekty te można wzajemnie łączyć, tworząc wielopoziomowe struktury:

JSONObject json = new JSONObject();
json.put("napis", "to jest napis");
json.put("liczba", new Integer(999));

JSONArray tab = new JSONArray();
tab.add("111");
tab.add(new Integer(222));
tab.add(new Double(333.33));

json.put("tablica", tab);
out.print(json);
 

Rezultat:

{"napis":"to jest napis","liczba":999,"tablica":["111",222,333.33]}
 

Przykład 3

Prezentacja wideo:

Zobacz prezentacje wideo

JSON in Java

JSON.simple jest prostą, aczkolwiek w kompletną biblioteką.

Jeżeli jednak potrzebujemy więcej, należy sięgnąć do innych. Pełniejszą odmianą JSON.simple jest „JSON in Java? (http://www.json.org/java/index.html). Instalacja oraz wykorzystanie jest bardzo zbliżone do JSON.simple. Biblioteka oprócz prostego tworzenia danych JSON, umożliwia też łatwiejsze jego odczytywanie, wspiera konwersje z/do XML oraz zawiera kilka mniej ważnych elementów, których pozbawiona jest uproszczona wersja.

JSON-lib

Obydwie wyżej opisane biblioteki są zgodne ze standardem JSON. Wprowadza to pewne ograniczenia, na przykład w kwestii przesyłania funkcji.
Dużo bardziej liberalna i rozbudowana jest biblioteka json-lib (json-lib.sourceforge.net) rozprowadzana na licencji Apache 2.0.

Instalacja nie jest w tym wypadku tak prosta, bowiem json-lib posiada listę zależność zawierającą:
xom (http://www.xom.nu/)
commons-lang (http://jakarta.apache.org/commons/lang/)
commons-beanutils (http://jakarta.apache.org/commons/beanutils/)
ezmorph (http://ezmorph.sourceforge.net/)

Należy zainstalować wymagane zależności, a na końcu pobrać plik jar odnoszący się do json-lib (json-lib-1.0b1-jdk13.jar lub json-lib-1.0b1-jdk15.jar). Wszystkie pliki jar umieszczamy w podkatalogu WEB-INF/lib na serwerze. Po odświeżeniu danych serwera zostanie udostępniona przestrzeń nazw net.sf.json.*

Podstawowe użycie jest analogiczne jak wyżej (przykłady pochodzą w części ze strony http://json-lib.sourceforge.net):

int[] array = new int[]{1,2,3};
JSONArray jsonArray = JSONArray.fromObject( array );
out.print(jsonArray);
 

wypisze:

[1,2,3]
 

Natomiast:

List list = new ArrayList();
list.add( "A" );
list.add( "B" );
JSONArray jsonArray = JSONArray.fromObject( list );
out.print( jsonArray );
 

wypisze:

["A","B"]
 

W kolejnym przykładzie widać utworzenie prostej funkcji:

Map map = new HashMap();
map.put( "name", "json" );
map.put( "bool", Boolean.TRUE );
map.put( "int", new Integer(1) );
map.put( "arr", new String[]{"a","b"} );
map.put( "func", "function(i){ return this.arr[i]; }" );
JSONObject json = JSONObject.fromObject( map );
out.print( json );
 

zwróci:

{"func":function(i){ return this.arr[i]; },"arr":["a","b"],"int":1,"name":"json","bool":true}
 

Wielką przewagą json-lib nad podobnymi bibliotekami jest możliwość serializacji klas języka Java do postaci JSON:

class MyBean{
    private String name = "json";
    private int pojoId = 1;
    private char[] options = new char[]{‘a’,‘f’};
    private String func1 = "function(i){ return this.options[i]; }";
    private JSONFunction func2 = new JSONFunction(new String[]{"i"},"return this.options[i];");

    // getters & setters
    …
}

JSONObject jsonObject = JSONObject.fromObject( new MyBean() );
System.out.println( jsonObject );
 

kod zwróci:

{"name":"json","pojoId":1,"options":["a","f"],
"func1":function(i){ return this.options[i];},
"func2":function(i){ return this.options[i];}}
 

W czasie konwersji obiekty klasy JSONFunction są zamieniane na funkcje języka JavaScript.
Możliwa jest także konwersja w drugą stronę.

Dodatkowo json-lib pozwala na konwersje formatu JSON na XML i odwrotnie.

Bardziej szczegółowy opis JSON można znaleźć w dokumencie: http://www.ietf.org/rfc/rfc4627.txt

Ajax Kurs cz. 1:
http://www.tpython.com/index.php/2007/08/23/kurs-ajax-cz1/