\n\n
\n

To wszystko oczywiście tylko pobieżny przykład, ale jak widać wystarcza do działania, a dzięki swojej prostocie nie będzie trudno go rozbudować o taką funkcjonalność, jaka będzie potrzebna. Polecam chociażby zainteresowanie się klasą GMarker, dzięki której możemy wstawiać na naszą mapkę informacje o zaznaczonych punktach.

","publishedAt":"2009-06-05T06:12:41Z","view":"views/sites/display/blog.xhtml","url":null,"commentingEnabled":true,"category":{"name":"Blog","slug":"blog","view":"views/sites/list/blog.xhtml","siteView":"views/sites/display/blog.xhtml"},"tags":[{"name":"Web","slug":"web"},{"name":"JavaScript","slug":"javascript"},{"name":"Tutorial","slug":"tutorial"},{"name":"Google","slug":"google"}]},{"name":"Ciekawostka o okładce Red Alert 3","slug":"ciekawostka-o-okladce-red-alert-3","content":"

Nie, ja nie gram

\n

Generalnie nie gram w gry. Primo nie mam na to czasu, secundo nie kręcą mnie w sumie, tertio szczerze mówiąc obecnie wychodzi tyle chłamu, że nawet nie warto się dotykać za większość tych kaszanowatych kopii starych przebojów z obciętą grywalnością nastawionych na fajerwerkową grafikę. Ale jest kilka serii, z tych, które istnieją do dziś, które darzę sentymentem (nawet jeśli kolejne części są coraz gorsze). Jedną z takich serii jest Command & Conquer. Jej ostatnią odsłoną jest Red Alert 3 (a nawet jest już do niego dodatek - Uprising). Nie grałem w niego przede wszystkim ze względu na brak czasu, oraz drugie przede wszystkim ze względu na niewystarczający sprzęt (dlaczego już nikt nie robi gier, które mieszczą się na flopce i wystarcza im kilka kB RAMu? \":(\"). Niemniej po zakupie, bądź co bądź chyba bardziej z przyzwyczajenia, niż w celu rozkoszowania się przesłodzoną grafiką, dodatku jakoś tak otworzyłem pudełko od podstawki i zauważyłem pewną ciekawostkę, którą wam zaprezentuję, bo chyba niewielu w ferworze walki z przeciwnikiem to zauważyło, a że ja grać nie miałem jeszcze okazji, to przynajmniej pudełko trochę przestudiowałem - otóż jeśli komuś nie pasuje komunistyczna propaganda na domyślnej okładce może ją sobie zmienić!

\n

Tuning okładki

\n

Oto okładka, którą znają wszyscy. Jednak jeśli ją wyjmiemy to zauważymy, ma ona drugie dno:

\n\"Pudełko\n\"Każdka\n\"Pudełko\n

W sumie po znalezieniu wewnątrz opakowania plakatu ze wszystkimi ponętnymi zachętami do grania nie dziwi mnie też ten dodatkowy bonus, bo nie od dziś EA lepiej działa w marketingu, niż w tworzeniu gry, no ale ciekawostka taka \"B)\".

","publishedAt":"2009-05-11T20:37:57Z","view":"views/sites/display/blog.xhtml","url":null,"commentingEnabled":true,"category":{"name":"Blog","slug":"blog","view":"views/sites/list/blog.xhtml","siteView":"views/sites/display/blog.xhtml"},"tags":[{"name":"Ciekawostki","slug":"ciekawostki"},{"name":"Gry","slug":"gry"},{"name":"Rozrywka","slug":"rozrywka"}]},{"name":"SVN w praktyce","slug":"svn-w-praktyce","content":"

System kontroli wersji

\n

Na początku zawsze jest chaos. Brak jakiegokolwiek planu działania, porządku, schematów - tylko wolność i swoboda. Tak zaczyna chyba każdy, kto w domowym zaciszu próbuje stawiać pierwsze kroki w programowaniu. Nie ma potrzeby, żeby programy dzielić na kilka plików, kod mający kilkadziesiąt, góra kilkaset linijek to już tasiemiec - kompiluje się go w ułamku sekundy i sprawdza czy działa; jeśli nie to patrzy dlaczego, jeśli tak to sprawdza, dlaczego tak, a nie inaczej. Zazwyczaj całe środowisko pracy to sam notatnik (wiem, że nie każdy używa Windows, ja pierwsze programy pisałem pod Linuksem i Amiga Workbench, ale przejmijmy, że to synonim \"prostego edytora tekstu\"). Z czasem jednak wszystko się rozwija - zaczyna się tworzyć coraz bardziej złożone rzeczy, notatnik zastępuje się IDE, odkrywa się, że zamiast wypisywać w każdej linijce śledzoną zmienną, można posłużyć się debuggerem. Ale wraz ze wzrostem złożoności tworzonych projektów trudniejsze jest nie tylko ich rozwijanie, ale również utrzymywanie - zaczyna się zauważać, jak wiele czynności staje się żmudnych i czasochłonnych. Zaczyna się pracować z innymi ludźmi i zachodzi potrzeba kontroli nad kodem (oraz innymi elementami projektów). Jednym z najbardziej pomocnych narzędzi zarówno przy samodzielnym grzebaniu w jakimś bardziej złożonym oprogramowaniu, jak i w pracy w zespole jest system kontroli wersji.

\n

System kontroli wersji to narzędzie służące do zarządzania zamianami zachodzącymi w plikach. Udostępnia narzędzia/opcje wspomagające takie operacje jak scalanie, nanoszenie łat, śledzenie zmian, cofanie zmian, oraz wiele wiele innych. Prędzej, czy później każdy z systemem wersji się zetknie (w takiej, czy innej postaci). Przy większych przedsięwzięciach jest on praktycznie niezbędny. Kiedy może się nam on przydać? Powiedzmy, że tworzymy złożony system, musimy rozwiązać jakąś fundamentalną sprawę, jak na przykład kontrola dostępu. Jeśli za miesiąc się okaże, że zapędziliśmy się w ślepy zaułek i zamiast na przykład zwykłego poziomu dostępu potrzeba użyć masek bitowych, to nie musimy zaczynać od początku. Cofamy się do momentu, sprzed takiego wyboru (a może nawet część pracy wykonanej potem da się zachować i użyć w podobny sposób). Inny przykład - pracujesz z inną osobą w tym samym pliku nad innymi rzeczami: ty nad odczytem danych z pliku, on(a) nad wypisywaniem (przyjmijmy, że te rzeczy dzieją się w tym samym pliku \":P\") - możecie spokojnie pracować i po prostu przesłać swoje zmiany, a system naniesie je obie. Praca z samym kodem praktycznie się nie zmienia, nie potrzebne są żadne specjalne czynności - pracuje się na zwykłych plikach. W wielkim uproszczeniu możesz na razie wyobrazić sobie system kontroli wersji jako wyspecjalizowany serwer FTP.

\n

Opiszę tutaj obsługę systemu SVN, ale to nie jedyne tego typu rozwiązanie - jest on po prostu najbardziej popularny (ze względu na łatwość obsługi i relatywnie małą złożoność). Oprócz SVN warto zainteresować się chociażby oprogramowaniem git - systemem kontroli wersji w architekturze P2P. Są też komercyjne rozwiązania tego typu. Ogólnie rzecz biorąc SVN zazwyczaj po prostu wystarcza. Wsparcie dla SVN możemy uzyskać w chyba każdym powszechnie używanym IDE, nawet jeśli nie ma go domyślnie, to poprzez wtyczki.

\n

Tworzenie repozytorium

\n

System SVN jest zorganizowany w strukturze klient-serwer. Na serwerze jest przechowywane tak zwane repozytorium, które zawiera wszystkie dane. Po stronie klienta jest tworzona jedynie tak zwana kopia robocza, czyli wycinek danego miejsca repozytorium oraz zadanej wersji - nie musimy pobierać całego repozytorium, może ono przechowywać wiele projektów, wiele gałęzi projektów - możemy pobrać tylko interesującą nas lokalizację. Do zarządzania systemem po stronie serwera służy program svnadmin. Najlepiej zacząć od wpisania polecenia:

\n
svnadmin help
\n

Dostaniemy listę wszystkich dostępnych komend. Wpisując dodatkowo na końcu jedną z nich program wypisze nam szczegółową pomoc dotyczącą tej komendy. Aby utworzyć repozytorium używamy komendy create oraz wskazujemy miejsce, gdzie chcemy utworzyć repozytorium. Ale uwaga - repozytorium, a nie nasz kod. Repozytorium to miejsce, gdzie serwer będzie magazynował dane, użytkownik zawsze pracuje na kopii roboczej (dane serwera są zapisane bazie danych więc to nie ważne, czy mamy repozytorium na tej samej maszynie, czy gdzieś indziej - i tak nie możemy edytować plików bezpośrednio w repozytorium). Powiedzmy, że utworzymy sobie repozytorium:

\n
svnadmin create /home/wrzasq/svnrepo
\n

Teraz, kiedy już mamy utworzone repozytorium tworzymy przypisaną do niego swoją kopię roboczą na której będziemy pracować. Robimy to poleceniem svn checkout (w skrócie svn co):

\n
svn co file:///home/wrzasq/svnrepo/ /home/wrzasq/svnwork/
\n

Polecenie to w praktyce utworzy nam katalog pusty (prawie) /home/wrzasq/svnwork/ z ukrytym katalogiem .svn, który zawiera dane dotyczące przypisanego repozytorium. Od tej pory wszystkie polecenia svn wykonywane w tym katalogu (i podkatalogach) będą się odnosiły do tej kopii roboczej (i wykonywane będą na przypisanym repozytorium).

\n

Kontrola dostępu

\n

Zanim zaczniemy pracę, przyda się jakoś skonfigurować nasze repozytorium, szczególnie pod kątem praw dostępu do niego. Jeśli pracujemy sami, a nikt inny do repozytorium nie ma dostępu to nie ma takiej potrzeby, ale dobrze wiedzieć jak to się robi. Konfiguracja repozytorium trzymana jest w podkatalogu conf w dwóch plikach:

\n\n

Oprócz tego możemy poszczególnym użytkownikom ograniczyć dostęp do repozytorium definiując reguły w pliku wskazywanym przez parametr authz-db, ale nie zapędzajmy się. Ważne też, żeby pamiętać, że jest to konfiguracja serwera - my na razie pracujemy lokalnie (protokół file://), więc żadnych skutków tych ustawień nie odczujemy.

\n

Dodawanie plików

\n

Mamy już repozytorium i mamy już swoją kopię roboczą. Teraz czas wrzucić jakieś pliki. Praktycznie wszystkie operacje wykonujemy na swoim systemie plików - tworzymy pliki, edytujemy je, usuwamy. Kiedy już utworzymy pliki (powiedzmy pusty plik o nazwie test.php) dodajemy go do kontroli wersji poleceniem:

\n
svn add test.php
\n

Oczywiście w przypadku większych zmian takich plików będzie bardzo dużo - zamiast podawać nazwę pliku możemy wpisać gwiazdkę - svn add * doda nam wszystkie pliki włącznie z podkatalogami więc nie ma strachu. Teraz wpiszmy sobie coś do pliku (nie, nie jestem takim masochistą na codzień \";)\", chcę, żeby kod był prosty, ale żeby dało się go zmienić w kilku miejscach):

\n
class HelloWorldClass\n{\n    const TEXT = 'Hello World!';\n\n    public static function print()\n    {\n        echo '<p>', self::TEXT, '</p>';\n    }\n}\n\nHelloWorldClass::print();
\n

Aby zmiany zapisać w systemie musimy je zaksięgować. Robimy to komendą commit, w skrócie ci (program zapyta się o opis zmian - to zwykły tekst, który możemy wpisać, aby nie było w przyszłości problemów z połapaniem się \"co autor miał na myśli\" w ferworze zmian):

\n
svn ci
\n

W tym miejscu zaznaczę też, że system kontroli wersji działa na serwerze - zapisuje zmiany, które się do niego wysyła. Nie pamięta on każdego kliknięcia, każdego zmienionego znaku dopóki mu tej zmiany nie wyślemy, więc dopóki nie zaksięgujemy zmiany w systemie, nie mamy możliwości korzystania z tego systemu.

\n

Możemy teraz wykonać svn co do innego katalogu i zobaczymy, że nasz plik został zapisany w repozytorium:

\n
svn co file:///home/wrzasq/svnrepo/ /home/wrzasq/test/
\n

Aby z kolei ściągnąć do swojej kopii roboczej zmiany naniesione w repozytorium przez innych użytkowników używamy polecenia update (w skrócie up).

\n

Zarządzanie plikami

\n

Zmiany w istniejących plikach będą wyłapywane przez system automatycznie. Inaczej sprawa się ma z samymi plikami - jeśli na przykład skopiujemy plik w swojej kopii roboczej, system nie będzie wiedział, że dany plik to kopia istniejącego już pliku, a szkoda tracić bardzo ważną funkcję SVN - potrafi on śledzić nie tylko zmiany w plikach, ale również same pliki (ich kopiowanie i zmianę nazwy). Polecenia SVN w tym zakresie są dość podobne do standardowych poleceń powłoki UNIX - cp służy do kopiowania, rm do usuwania, a mv do zmiany nazwy (przy czym ta ostatnia w przypadku SVN to po prostu wykonanie cp, a następnie usunięcie pierwowzoru. Spróbujmy zatem przetestować te możliwości kopiując test.php jako index.php:

\n
svn cp test.php index.php
\n

Powinniśmy dostać informację podobną do tej, jaka pojawia się po zwykłym dodaniu pliku, ale wcale nie było to zwykłe dodanie. Bardzo łatwo sprawdzić stan repozytorium poleceniem status (w skrócie st), które wypisuje wszystkie zmiany w obecnej kopii roboczej, które nie zostały zaksięgowane - powinno obok dodanego pliku wypisać znak +, co oznacza, że posiada on dodatkowe informacje dotyczące pierwowzoru:

\n
svn st
\n

Teraz skoro mamy drugi plik nie potrzebujemy pierwszego, więc go usuniemy:

\n
svn rm test.php
\n

Innymi dwoma przydatnymi poleceniami, które bardzo przydadzą się przy zarządzaniu plikami są polecenia dotyczące zmian w samych plikach. Pierwsze z nich, diff (w skrócie di) jak sama nazwa wskazuje wykonuje prace podobną do programu diff (a wręcz go używa) - pokazuje ono różnice między plikami. W przypadku SVN jednak główny sens nie polega na porównywaniu różnych plików, ale różnych wersji tego samego pliku, dlatego mamy możliwość podania jako parametrów wersji zadanych plików. W szczególnej (ale najbardziej przydatnej) wersji pokazuje ono zmiany naniesione w danym pliku w naszej kopii roboczej względem ostatniej zaksięgowanej zmiany - wpisanie w naszym przypadku:

\n
svn di test.php
\n

Wypisze nam cały plik, ponieważ w ostatniej zaksięgowanej zmianie ten plik istniał, a obecnie go usunęliśmy.

\n

Drugie polecenie to cofanie naniesionych zmian. Polecenie to nazywa się revert (a nie ma skrótu \":P\"). Jednak przez cofanie zmian nie rozumie się tutaj cofanie do innej wersji - cofa jedynie niezaksięgowane zmiany (przywraca najnowszą wersję), o przywracaniu innych wersji napiszę potem. Jeśli zatem chcemy odzyskać nasz plik, możemy użyć svn revert test.php (możemy też po prostu ściągnąć go z powrotem z repozytorium).

\n

No to zapisujemy zmiany (svn ci) i idziemy do następnego punktu.

\n

Gałęzie i tagi

\n

W czasie rozwijania projektu nieraz przychodzi potrzeba rozwidlenia. Tagi (etykiety) to pewne zapisane wersje (zazwyczaj na takich zapisanych kopiach już się nie pracuje - stanowią one stały punkt dostępu na przykład do starszych wersji stabilnych). Gałęzie to odrębne strumienie rozwoju (czasem rozwijane jako alternatywa, a czasem jako po prostu wydzielona grupa zmian, po wykonaniu których zmiany zostaną wcielone do głównego drzewa). Nie będę się rozwodził nad organizacją repozytorium, nad organizacją samego projektu i tego typu zagadnieniami, więc załóżmy prosty przykład. Tworząc grę trzeba stworzyć nowy mechanizm do obsługi sieci, bo stary jest niewydajny. Praktycznie oznacza to konieczność napisania go od nowa. Gdyby zmiany na bieżąco nanosić na jedną i tę samą kopię, to aż do ukończenia prac nad nową obsługą sieci, cały program przestałby działać. Przydaje się więc stworzyć oddzielną kopię, gdzie odpowiedzialny za nią zespół będzie osobno pracował nad mechanizmami sieciowymi, podczas gdy główna gałąź (trunk) będzie oparty o stare, ale działające rozwiązania. Praktycznie osiąga się to przez zwykłe kopiowanie (svn cp) danego katalogu jako nowego. Jednak w praktyce przyjęło się stosować pewną konwencję, która określa strukturę katalogów trunk-tags-branches:

\n
|-- trunk # to główna gałąź, czyli wersja podstawowa\n|-- tags # zamrożone stany ważnych punktów\n|   |-- ver2.2 # na przykład zapisana starsza wersja 2.2\n|   `-- ver2.3 # i wersja 2.3\n`-- branches # odrębne gałęzie rozwojowe\n    |-- newnetwork # przykładowa gałąź do pracy nad nową obsługą sieci\n    |-- newdb # nowa baza danych\n    `-- newdb2 # alternatywna baza danych - po testach okaże się, która jest lepsza i ta zostanie wcielona do drzewa 'trunk'
\n

Jednak jest to tylko (ale wolę o tym myśleć, jako \"aż\") konwencja i nie wprowadza żadnych systemowych zależności (chociaż wiele programów jest do niej przystosowanych i domyślnie takiej struktury używa, więc dobrze jest jej używać). My stworzymy sobie pseudo-gałąź jako po prostu osobny plik, powiedzmy, że nazwiemy go revindex.php:

\n
svn cp index.php revindex.php
\n

Wykonujemy svn ci i idziemy dalej.

\n

Scalanie

\n

Dochodzimy do najważniejszej chyba części jeśli chodzi o obsługę systemu wersji, czyli modyfikacja plików i ich scalanie. Żeby mieć jakieś podstawy do pracy wprowadźmy następujące zmiany do naszych plików (zaksięgujemy każdy plik osobno, a więc po edycji każdego pliku wykonajmy svn ci) - niech index.php zawiera (zmieniony tekst):

\n
class HelloWorldClass\n{\n    const TEXT = 'Tutorial SVN - https://wrzasq.pl/';\n\n    public static function print()\n    {\n        echo '<p>', self::TEXT, '</p>';\n    }\n}\n\nHelloWorldClass::print();
\n

svn ci i idziemy do revindex.php, gdzie zmienimy sposób wyświetlania:

\n
class HelloWorldClass\n{\n    const TEXT = 'Hello World!';\n\n    public static function print()\n    {\n        echo '<pre>', self::TEXT, '</pre>';\n    }\n}\n\nHelloWorldClass::print();
\n

Ponownie wykonujemy svn ci. Teraz mamy dwa pliki zawierające równoległe zmiany: w pierwszym zmieniliśmy treść, w drugim wygląd. Obie zmiany nam pasują, więc chcemy nanieść te z pliku revindex.php do oryginału. Do łączenia plików służy polecenie merge (nazwa również nieprzypadkowo taka sama jak program merge):

\n
svn merge file:///home/wrzasq/svnrepo/revindex.php index.php
\n

Jeśli teraz wykonamy svn di index.php zauważymy, że zmiana sposobu wyświetlania została naniesiona. Jeśli otworzymy plik zobaczymy również, że wyświetlana treść nie zmieniła się - nadal jest nowa. Teraz możemy już usunąć nasz plik \"rozwojowy\" revindex.php. Ale powiedzmy, że w pewnym momencie dochodzimy do wniosku, że jednak stary sposób był lepszy. Jak cofnąć zmiany już naniesione? W praktyce odbywa się to również przez scalanie, po prostu jako nośnik zmian podajemy starszą wersję. Jeśli wszystko robiłeś krok-po-kroku tak jak tu opisuję, to przed zmianą powinna być wersją 5 (a jeśli jednak coś majstrowałeś, to i tak nie powinno być problemu ze znalezieniem potrzebnej wersji - wiele informacji jest wypisywanych na ekran podczas pracy więc pewnie zauważyłeś jaki to był numer wersji - jeden mniejszy niż ta po poprzednim scaleniu). No więc tym razem wywołujemy merge, tyle, że podajemy dodatkowo numery wersji i to, co ważne, w odwrotnej kolejności (a potem już standardowo svn ci):

\n
svn merge file:///home/wrzasq/svnrepo/index.php index.php -r 6:5
\n

Jednak te zmiany nie były zbyt złożone, nie trzeba było oczywiście tworzyć dla nich osobnej \"gałęzi\" (że tak to dumnie w tym wypadku nazwę \";)\"). Jak już na początku wspomniałem sam system również śledzi zmiany, rozgałęzianie kodu ma sens, gdy nad jedną i tą samą rzeczą pracuje się na kilka sposobów, lub gdy nie chce się burzyć całego systemu. Aby zobaczyć jak sam system sobie radzi stwórzmy sobie drugą kopię roboczą:

\n
svn co file:///home/wrzasq/svnrepo/ /home/wrzasq/svnwork2/
\n

Ponownie wprowadźmy w dwóch plikach różne zmiany - w pliku /home/wrzasq/svnwork/index.php zapiszmy (zmienił się tekst wypisywany):

\n
class HelloWorldClass\n{\n    const TEXT = 'Tutorial SVN - <a href=\"https://wrzasq.pl/\" title=\"Wrzasq.pl - tworzenie storn i aplikacji internetowych.\">https://wrzasq.pl/</a>';\n\n    public static function print()\n    {\n        echo '<p>', self::TEXT, '</p>';\n    }\n}\n\nHelloWorldClass::print();
\n

Natomiast w pliku /home/wrzasq/svnwork2/index.php zapiszmy (zmiana nazwy klasy i metody):

\n
class HelloWorld\n{\n    const TEXT = 'Tutorial SVN - https://wrzasq.pl/';\n\n    public static function output()\n    {\n        echo '<p>', self::TEXT, '</p>';\n    }\n}\n\nHelloWorld::output();
\n

Jeśli teraz wykonamy svn ci w jednym z katalogów, to w drugim operacja ta będzie niemożliwa, ale bez paniki - to tylko zabezpieczenie. Aby mieć pewność, że zmiany nie nachodzą na siebie SVN nie pozwala przesyłać zmian dopóki nie uaktualni się swojej kopii roboczej do wersji z repozytorium. Wystarczy wykonać:

\n
svn up && svn ci
\n

Teraz w drugim katalogu również wykonujemy svn up. Możemy teraz sprawdzić - obydwa pliki są takie same, zawierają zmiany naniesione z obydwu źródeł. Czasem w tym wszystkim idzie się pogubić. Szczególnie jeśli pracuje się w zespole. Użyteczne w takiej sytuacji polecenie to blame - wypisuje ono informacje o zmianach konkretnych linijek (wraz z użytkownikiem wprowadzającym te zmiany) danego pliku:

\n
svn blame index.php
\n

Dobre nawyki

\n

Jak zawsze oprócz ograniczeń technicznych, albo indywidualnych upodobań istnieją pewne zasady, których przyjęło się przestrzegać, lub po prostu dobrze jest się do nich stosować (na przykład ze względu na bezpieczeństwo danych). Wspominałem już chociażby o strukturze katalogów. Tak jak też napomknąłem, pracując z Subversion dobrze jest używać jego poleceń do chociażby przenoszenia plików, gdyż daje to możliwość dalszego śledzenia zmian. Dobrze jest też regularnie używać polecenia update, aby mieć pewność, że pracujemy na aktualnej wersji.

\n

Logi

\n

Inną bardzo ważną rzeczą jest tworzenie logów. Zapewne zauważyłeś, że przy każdym księgowaniu zmian system otwiera edytor i prosi cię o wpisanie opisu. Nawet jeśli używasz repozytorium samemu, warto wpisywać opis wprowadzanych zmian. Kiedyś ilość zmian w jednym pliku osiągnie nawet bardzo niewielką ilość - powiedzmy kilkanaście, możesz mieć problemy z określeniem, w którym miejscu konkretna zmiana miała miejsce, a teraz wyobraź sobie prace z ludzi, którzy jeszcze muszą to zgadywać w ciemno - ktoś kiedyś powiedział, że należy zawsze pisać tak, jakby ten kto ma potem utrzymywać kod był psychopatycznym mordercą znającym twój adres.

\n

Dry-run

\n

Uruchamianie \"na sucho\" jest szczególnie ważne w przypadku operacji merge - jeśli coś pójdzie nie tak jesteśmy, że tak powiem, w czarnej dupie. Zawsze dobrze jest najpierw użyć opcji \"na sucho\", czyli dodać do polecenia argument --dry-run - wypisze ona spodziewane rezultaty, ale nic nie zapisze na dysku. Tak, Subversion już dawno jest w fazie produkcyjnej, ale strzeżonego… wiecie.

\n

Backup repozytorium

\n

Skoro już mamy coś w repozytorium to szkoda, żeby kiedyś trafił to szlag. Na szczęście można zarzucać zawartość repozytorium i bezpiecznie przechowywać jego backup, ale aby się dobrać do samego repozytorium, będziemy musieli się posłużyć ponownie programem svnadmin. Do tworzenia zrzutu służy komenda dump - wypisuje ona zawartość wszystkich kolejnych wersji na standardowe wyjście, więc wystarczy przekierować jego strumień do pliku:

\n
svnadmin dump /home/wrzasq/svnrepo/ > backup
\n

Do odzyskiwania takiej kopii służy z kolei polecenie load. Skoro mamy kopię bezpieczeństwa, to możemy śmiało usunąć obecne repozytorium - usuwamy więc cały katalog /home/wrzasq/svnrepo/. Teraz stworzymy w jego miejsce puste repozytorium (polecenie jak na początku artykułu), a następnie wczytamy do niego zawartość pliku zrzutu - to polecenie z kolei sczytuje dane ze standardowego wejścia:

\n
svnamdin load /home/wrzasq/svnrepo/ < backup
\n

Przenoszenie katalogów

\n

Czasami jednak dzieje się tak, że chcemy \"wyciągnąć\" historię jedynie jakiegoś wycinka repozytorium (chociażby żeby przenieść całą historię do innego repozytorium). Do tego trzeba zastosować osobny program - svndumpfilter, który filtruje zawartość zrzutu i wybiera jedynie pasujące elementy. Ponieważ użycie w praktyce w naszym przypadku wymagałoby zbyt dużego grzebania w naszym małym przykład pokażę jedynie przykłądowe zastosowanie:

\n
svnadmin dump /home/wrzasq/svnrepo/ | svndumpfilter include projekt1 | svndumpfilter exclude projekt1/branches | svndumpfilter include projekt1/tags/test > backup
\n

Polecenie to może wykluczać (exclude), albo wybierać (include) ścieżki ze zrzutu. Wypisuje ono dalej przefiltrowaną zawartośc, dlatego jak widać można takie filtry ze sobą łączyć. W tym wypadku filtr wybierze tylko katalog projekt1 z katalogu głównego, ale odrzuci jego dwa podkatalogi: branches i tags/test.

\n

Udostępnianie repozytorium

\n

Ostatnią przydatną umiejętnością jest udostępnianie repozytorium. SVN obsługuje wiele protokołów (chociażby HTTP korzystając z WebDAV, czy użycie SSH jako szyfrowania). Jednak żeby nie rozpisywać się zbytnio, ograniczę się do tego najbardziej podstawowego sposobu - odpalania zwykłego daemona. Wykorzystuje on protokół SVN (svn://). Domyślnie deamon pracuje na porcie 3690. Serwer uruchamiamy poleceniem svnserve. Musimy podać tryb pracy (jako argument) - mamy do wyboru tryb samodzielny (-d), tryb z użyciem super-serwera inet (-i), jako tunel (-t), lub w celach diagnostycznych tylko na jedno połączenie (-X). W sumie nas interesują tylko te dwa pierwsza, a żeby ułatwić sprawę, po prostu odpalimy serwer jako samodzielnego daemona, czyli opcja pierwsza. Jeśli uruchamiamy serwer w katalogu repozytorium, to svnserve -d w zupełności wystarczy. Możemy też uruchomić go z innego katalogu, podając lokalizację repozytorium jako parametr:

\n
svnserve -d /home/wrzasq/svnserve/
\n

Ta forma jest znacznie bardziej przydatna, chociażby przy tworzeniu skryptów uruchomieniowych. Oprócz tego możemy przy pomocy parametru --listen-port zmienić port, na którym nasz serwer będzie nasłuchiwał połączeń. Teraz inni nasi współpracownicy będą mogli się połączyć klientem SVN używając prostego URLa (względnie jeśli uruchamiasz serwer na innym porcie koniecznie będzie dodanie :port):

\n
svn://twoj.adres.lub.domena/
\n

Oprogramowanie

\n

Ten tutorial opracowałem w oparciu o podstawowe oprogramowanie Subversion. Jest ono dostępne na chyba większość popularnych platform. Ale zapewne wielu ludzi odstrasza wizja korzystania z konsoli do każdej tego typu operacji - nic takiego, oczywiście istnieją graficzne oprogramowania klienckie. Większość z nich bardzo dobrze integruje się z powłoką systemową dzięki czemu praktycznie nie odczuwa się dodatkowego obciążenia w pracy z SVN, a jedynie korzysta z jego zalet. Wśród takich rozwiązań na pewno przoduje TortoiseSVN - klient pod Windowsa. Pod Linuksa bardzo wygodne jest KDE SVN. Oprócz tego tak jak wspominałem większość IDE posiada wsparcie dla różnego rodzaju systemów kontroli wersji, w tym dla SVN praktycznie większość - Eclipse, NetBeans, czy Visual Studio, dla pozostałych z pewnością też coś się znajdzie.

","publishedAt":"2009-04-23T02:04:55Z","view":"views/sites/display/blog.xhtml","url":null,"commentingEnabled":true,"category":{"name":"Blog","slug":"blog","view":"views/sites/list/blog.xhtml","siteView":"views/sites/display/blog.xhtml"},"tags":[{"name":"Subversion","slug":"subversion"},{"name":"Praca","slug":"praca"},{"name":"Tutorial","slug":"tutorial"},{"name":"Organizacja","slug":"organizacja"},{"name":"Projekty","slug":"projekty"}]},{"name":"Od podstaw: XML","slug":"od-podstaw-xml","content":"

XML

\n

XML to \"rozszerzalny język znaczników\" (ang. eXtensible Markup Language). Oznacza to, że jest to język uniwersalny przeznaczony do tworzenia języków oznaczeń - sam w sobie jest jedynie zbiorem zasad składni, definiuje pewne mechanizmy rządzące dokumentem, nie definiuje za to żadnych znaczników ani atrybutów. Innymi słowy XML określa jedynie format zapisu, a nie format samych danych. Robią to dopiero języki oparte na XML-u takie jak XHTML, RSS i wiele innych. Sam XML jest pochodnym SGML, a ten z kolei wywodzi się z GML. Nie będę ich tutaj omawiał, jednak ich idea jest podobna. Zostały one opracowane w celu przechowywania i współdzielenia dokumentów w jednolity sposób na przestrzeni lat. XML jest w gruncie rzeczy uproszczoną wersją SGML - ogranicza jego implementacje tylko do domyślnej składni, ujednolica wiele zagadnień (jak chociażby \"puste\" tagi). O XML-u pewnie obiło się wielu osobą o uszy, często jednak nie zdają sobie sprawy jak ważne są niektóre jego aspekty. Widać to chociażby w przypadku stron WWW tworzonych w tej technologii (korzystając z języka XHTML).

\n

Podstawowym błędem jaki popełnia wiele osób zaczynających pracę z XML-em to traktowanie go jak zwykłego tekstu. Owszem - dokumenty XML zazwyczaj można edytować w zwykłym edytorze tekstu, jako znaki specjalne wykorzystują znaki z zakresu ASCII (<, > i kilka innych), ale wszystkie te znaki mają określone znaczenia, struktura dokumentu jest określona. Ich znaczenie, oraz wzajemne relacje (chociażby samej struktury drzewa opisanej niżej) powodują, że nieraz nierozważne modyfikowanie zawartości dokumentu prowadzi do zapisania go z błędami.

\n

Struktura dokumentu

\n

Tak, jak już wspomniałem strukturą dokumentu XML jest drzewo. Każda dana w dokumencie stanowi węzeł drzewa. Korzeniem tego drzewa jest element (o tym czym są elementy za chwilę). Poniżej przedstawiam opis tylko najważniejszych typów węzłów w drzewie XML - jest ich więcej (na przykład sam dokument też jest rodzajem węzła, węzłem też są komentarze i prolog dokumentu). Opis ten ma na celu jedynie słowne wyjaśnienie podstawowych pojęć - technicznych specyfikacji i dokładnych standardów należy szukać na stronie grupy roboczej XML przy W3C.

\n

Elementy

\n

Podstawowym typem węzła jest element. Każdy dokument ma co najmniej jeden element, wspomniany korzeń. Elementy na pewno wszyscy dobrze znają jako używane w (X)HTML-u znaczniki (tagi). Grupują one pozostałe elementy jako swoją zawartość - elementy to jedyne węzły, które mogą mieć potomków (czyli węzły w drzewie \"podpięte\" pod nie).

\n

Element obejmuje wszystko od znacznika początkowego, do końcowego. Jest to jedna z różnic między SGML, a XML - ten pierwszy dopuszczał istnienie znaczników otwierających bez odpowiadających im znaczników końcowych (najprostszym przykładem jest element BR z języka HTML). Znacznik zapisuje się wstawiając jego nazwę między nawiasy trójkątne (<, >), a znacznik końcowy oznacza się dopisując do nazwy z przodu znak /.

\n

W przypadku XMLa puste znaczniki również muszą posiadać znacznik końcowy, dopuszczalna jest jednak skrócona forma zapisu. Następujące dwa fragmenty dokumentów są poprawnie zapisanymi elementami br w XHTML-u (a więc i XML-u):

\n
<br></br>
\n
<br/>
\n

Atrybuty

\n

Atrybuty opisują pewne właściwości elementów. Zapisuje się je w formie nazwa=\"wartość\" (zamiast cudzysłowów dopuszcza się stosowanie apostrofów). Jest to kolejna zmiana w stosunku do SGML - tam wartości można było zapisywać bez ograniczników (w przypadku gdy wartość nie zawierała białego znaku), a nawet bez wartości (na przykład atrybut selected w HTML). W XML każdy atrybut musi mieć wartość, tak więc aby zaznaczyć wybraną opcję w liście rozwijanej w XHTML należy napisać:

\n
<option value=\"foo\" selected=\"selected\">Wybrana</option>
\n

Tekst

\n

Najważniejszy w każdym dokumencie jest przekaz. W przypadku XML często chodzi o przekaz tekstowy. Wartość tekstowa danego elementu jest wpisywana między jego początkowy i końcowy znacznik. Istnieją dwa sposoby wprowadzania tekstu. Może on zostać zapisany bezpośrednio, trzeba wtedy jednak pamiętać, o użyciu encji (o tym za chwilę) w przypadku znaków specjalnych XML-a. Drugi sposób to użycie tak zwanej sekcji CDATA:

\n
<element><![CDATA[\n    <foo>\n]]></element>
\n

Tekst zapisany w sekcji CDATA nie zostaje przetworzony jako XML - w tym wypadku <foo> jest traktowane jako zwykły tekst, a nie element. W sekcji takiej jednak nie można (w żaden sposób) przechowywać ciągu ]]>, jeśli więc chcemy zapisać go musimy skorzystać z dwóch sekcji CDATA oddzielonych zwykłym tekstem:

\n
<element>\n<!--\nten element po przetworzeniu będzie miał następującą zawartość tekstową:\n\npierwszy fragment tekstu\n]]>\ndrugi fragment tekstu\n\n -->\n<![CDATA[\npierwszy fragment tekstu\n]]>]]&gt;<![CDATA[\ndrugi fragment tekstu\n]]>\n</element>
\n

Encje

\n

Ostatnim z najważniejszych typów węzłów są encje - ang. entity. Są to odwołania do wcześniej zdefiniowanych identyfikatorów. Odwołania takie zostają w czasie przetwarzania podmienione z wartościami danych identyfikatorów. Podstawowym zastosowaniem jest wstawianie do dokumentów znaków specjalnych. Istnieje pięć pre-definiowanych encji, które dają możliwość zapisania wszystkich znaków używanych przez XML jako specjalne:

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
&lt;<
&gt;>
&amp;&
&quot;"
&apos;'
\n

Pierwsze dwa znaki są używane jako ograniczniki znaczników, ampersand jest używany do rozpoczęcia zapisu encji (na przykład, żeby zapisać &amp; należy odwołać się podwójnie, przez &amp;amp;). Ostatnie dwa znaki są używane jako ograniczniki wartości atrybutów - tak na prawdę poza atrybutami nie trzeba ich zastępować i można pisać bezpośrednio; ponadto jeśli ogranicznikiem wartości danego atrybutu jest cudzysłów, to nie trzeba podmieniać apostrofów, tak więc poniższy zapis jest w pełni poprawny:

\n
name=\"&quot;rock'n'roll&quot;\"
\n

Oprócz tego XML daje też możliwość zapisania dowolnego znaku jako odwołanie do tablicy Unicode używając kodu danego znaku:

\n\n\n\n\n\n\n\n\n\n\n\n
&#DDD;W zapisie dziesiętnym.
&#xHHH;W zapisie szesnastkowym.
\n

Tak więc znak < (&lt;) możemy zapisać również jako &#60; lub jako &#x3C;.

\n

Document Object Model

\n

Sam XML określa fizyczną strukturę dokumentu, jednak w reprezentacji cyfrowej jest to pojęcie niezwykle ogólne. Dlatego aby ustandaryzować pracę z dokumentami XML z poziomu kodu programu stworzono interfejs programistyczny o nazwie Document Object Model - w skrócie DOM. Jest on powszechnie używany i zaimplementowany na chyba wszystkie ważniejsze platformy, a w przypadku środowisk do pracy w środowisku internetowym (PHP5, JavaScript, Java i wiele innych) praktycznie jest on standardem. API to określa metody dostępu do węzłów, ich modyfikacji, tworzenia i wiele innych operacji.

\n

Jeśli mamy zamiar wykorzystywać w naszym oprogramowaniu formaty oparte na XML-u to DOM jest podstawą. Korzystając z niego mamy pewność, że przetwarzamy dokument we właściwy sposób (oczywiście pomijając możliwość błędu w samej bibliotece naszego środowiska \";)\"), a ponadto ułatwi nam to ewentualną migrację do nowego środowiska, albo reprodukcję kodu - w każdym DOM zadziała w taki sam sposób i korzysta się z niego również w niemal taki sam sposób w każdej dostępnej implementacji (takie jest założenie ale oczywiście istnieją zazwyczaj drobne różnice w zależności od języka).

\n

xml:id

\n

Bardzo ważnym rozszerzeniem podstawowej standaryzacji XML jest xml:id. Najprościej rzecz ujmując określa ono zasady identyfikacji elementów w dokumencie. W skrócie, który jednak nie ujmuje nic ważnego z całości, xml:id określa typ atrybutu, który jest unikalny w skali dokumentu - czyli posługując się jego wartością jesteśmy w stanie znaleźć szukany element (nie ma drugiej takiej wartości). W większości języków opartych na XML-u używa się do tego celu atrybutu id, jednak tutaj należy zaznaczyć bardzo ważną sprawę - sam dokument xml:id nie określa nazwy atrybutu, a jedynie jego typ. Oznacza to, że język musi określić, który atrybut będzie w nim oznaczał identyfikator. Na przykład poniższy kod wypisze bar, a nie foo!:

\n
$dom = new DOMDocument();\n$dom->loadXML('<!DOCTYPE element [\n\n<!ELEMENT element (element*)>\n<!ATTLIST element\n    id      CDATA   #IMPLIED\n    name    ID      #IMPLIED\n>\n\n]>\n<element>\n    <element id=\"bar\" name=\"foo\" />\n    <element id=\"foo\" />\n</element>');\n\necho $dom->getElementById('foo')->getAttribute('id');
\n

Sekcji DOCTYPE nie będę na razie tłumaczył - definiuje ona dla naszego typu dokumentu znacznik element, który może zawierać dwa atrybuty: id i name. Jednak jako identyfikator podaje ten drugi. Co więcej - bez tej sekcji w dokumencie w ogóle nie będziemy mogli wyszukiwać elementów, gdyż id nie jest nawet domyślnie atrybutem typu xml:id - nie jest niż żaden atrybut. Dlatego właśnie ważne jest zrozumienie, czym XML sam w sobie jest dla dokumentu - jedynie formatem zapisu, a to my musimy sami zatroszczyć się o jego prawidłową (oczekiwaną przez nas) interpretację pod kątem zawartości.

\n

DOM

\n

Rozszerzenie xml:id ma również bardzo duże znaczenie w aspekcie korzystania z interfejsu DOM. Jak widać w powyższym przykładzie interfejs ten udostępnia metodę getElementById() - to właśnie dzięki niej możemy bez trudu odnaleźć element o podanym przez nas identyfikatorze.

\n

Przestrzenie nazw

\n

Kolejnym ważnym mechanizmem rozszerzającym podstawowe zasady funkcjonowania XML-a są przestrzenie nazw. Idea ta jest pewnie znana z wielu języków programowania i w przypadku XML-a pełni podobną rolę - grupowanie identyfikatorów z jednego języka w jego przestrzeni nazw. Tyle, że w przypadku XML-a jest to znacznie bardziej ważne - jak już wiele razy zaznaczałem pracując z XML-em praktycznie samodzielnie tworzymy własny język, dlatego ważne jest aby zgrupować wszystko to, co w nim definiujemy i odizolować od reszty. Mechanizm przestrzeni nazw jest nieco inny niż te znane z języków programowania jak chociażby C++ - tutaj przestrzenią nazw jest po prostu prefiks nazwy danego elementu, lub atrybutu. Użycie przestrzeni nazw nie ładuje nam jej, nie dołącza żadnej biblioteki - po prostu grupuje dany element, lub atrybut. Jest to nieco mylące, szczególnie na początku, ale należy pamiętać, że XML sam w sobie jest kompletnie statyczny - to język formatowania dokumentów, a nie język programowania, który określa wykonywanie czynności.

\n

Jeszcze bardziej pokręcony może się wydawać na początku sposób użycia tej techniki. Samą przestrzenią nazw jest URI, natomiast w dokumencie tworzy się dla niej lokalny identyfikator:

\n
<root xmlns:foo=\"http://localhost/\" foo:bar=\"test\" />
\n

W tym wypadku tworzymy w dokumencie identyfikator foo dla przestrzeni nazw http://localhost/. Tworzenie przestrzeni nazw w dokumencie odbywa się za pomocą atrybutu xmlns w formie xmlns:identyfikator. Możemy także użyć samego atrybutu xmlns, ma to miejsce chociażby w przypadku stron napisanych w XHTML-u:

\n
<html xmlns=\"http://www.w3.org/1999/xhtml\" />
\n

W ten sposób definiujemy domyślną przestrzeń nazw. Jednak co jeszcze bardziej mylące - dana przestrzeń nazw nie jest żadnym fizycznym adresem (może, ale nie musi) - może być to nie istniejący URI, co więcej - nawet nie musi być to realny URI, musi być jedynie poprawny składniowo (ale oczywiście zalecane jest, aby pod adresem wskazywanym przez przestrzeń nazw znajdywał się jakiś powiązany z nią zasób).

\n

Przestrzenie nazw w XML dają ogromne możliwości - pozwalają na zagnieżdżanie elementów z różnych formatów w jednym dokumencie. Jest to jedna z największych korzyści jakie płyną z XHTML, który tym właśnie się różni od HTML-a, że jest aplikacją XML. Można na przykład osadzić obraz SVG bezpośrednio wewnątrz dokumentu XHTML:

\n
<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:svg=\"http://www.w3.org/2000/svg\">\n    <head>\n        <title>Przykład osadzania dokumentów XML</title>\n    </head>\n    <body>\n        <h1>Grafika SVG osadzona bezpośrednio w dokumencie XHTML</h1>\n        <svg:svg version=\"1.1\" baseProfile=\"full\" width=\"300px\" height=\"200px\">\n            <svg:circle cx=\"150px\" cy=\"100px\" r=\"50px\" fill=\"#ff0000\" stroke=\"#000000\" stroke-width=\"5px\"/>\n        </svg:svg>\n    </body>\n</html>
\n

Aby obejrzeć rezultaty potrzebna będzie przeglądarka z obsługa formatu SVG (na przykład Opera), a plik należy zapisać z rozszerzeniem .xhtml. Przykład zaczerpnięty ze strony https://jwatt.org/svg/demos/xhtml-with-inline-svg.xhtml, nieco oczyszczony. Na ekranie powinno się pojawić czerwone koło z czarną obwódką.

\n

Walidacja

\n

Bardzo ważnym elementem przetwarzania dokumentów XML jest walidacja, czyli sprawdzanie ich poprawności. Sam fakt, iż dokument udało się załadować jako strukturę danych świadczy jedynie, że jest to poprawnie zapisany dokument XML. Ponieważ w XML-u sami decydujemy o tym jaką strukturę mają mieć dane zapisane w dokumencie, sam procesor XML (mechanizm ładujący i przetwarzający dokumenty) nie jest w stanie sprawdzić ich poprawności pod kątem semantycznym, zbadać ich zależności. Do tego celu należy stworzyć definicje typów danych zawartych w dokumentach.

\n

Sposobów na to jest kilka, ja przedstawię tutaj trzy najważniejsze. Nie będę ich zbyt szczegółowo omawiał, ponieważ każdy z nich to temat na wiele osobnych stron artykułów.

\n

DTD

\n

Pierwszym sposobem opisu jest DTD - Document Type Definition. Jest to natywny sposób opisu zawartości dokumentu wywodzący się jeszcze z SGML - jest on bardzo prosty i prymitywny, jednak przez to również ograniczony. To właśnie w DTD została zapisana definicja danych w przykładzie obrazującym działanie xml:id. DTD ma jednak kilka cech, które stawiają je ponad pozostałymi sposobami opisu XML:

\n\n

Jednak jak już wspomniałem DTD jest bardzo ograniczone i pozwala tylko na podstawowy zakres definiowania struktury dokumentu. Ponadto używa on składni SGML, co w przypadku osób chcących pracować z samym XML-em może stwarzać niepotrzebne zamieszanie.

\n

XML Schema

\n

Nowszą technologią jest XSD (XML Schema Definition). Daje ona ogromne możliwości, znacznie większe niż te z DTD. Ponadto definicja stworzona przy pomocy tego języka jest sama w sobie również dokumentem XML, więc jest to wygodniejsze rozwiązanie dla osób obeznanych z XML-em.

\n

Ma ono jednak swoje wady. Po pierwsze nie da się załączyć definicji XML Schema do dokumentu. Walidacja na podstawie takiego schematu odbywa się \"na życzenie\", czyli należy po załadowaniu w kodzie naszego dokumentu wskazać procesorowi XML dodatkowo nasz schemat. Poza tym jako iż jest to również język oparty na XML, to i tak posiada on swój własny DTD opisujący jego składnię.

\n

Relax NG

\n

Podobnym rozwiązaniem do XSD jest Relax NG. Poza tym, że różni się składnią, to sama idea jest bardzo podobna, więc posiada on pod względem technicznym podobne wady i zalety. Jedyną większą różnicą jest fakt, iż język ten posiada drugą składnię, która nie jest składnią XML (kompaktowa).

\n

XML a (X)HTML

\n

Jaka jest relacja między XML-em, a HTML-em? Otóż bezpośredniej nie ma w ogóle. HTML to język oparty na SGML-u. Pisanie w nim jest nieraz wygodniejsze niż pisanie w XML-u, jednak wiąże się to z wadami ze strony technicznej - niejednoznaczność i nie konsekwentność w strukturze dokumentu. Implementacją HTML-a, w sztywnych regułach XML-a jest XHTML - jest to pełnoprawna aplikacja XML, zatem korzystanie z niego ma wiele zalet (możliwość zagnieżdżania dowolnych innych aplikacji XML, oraz zagnieżdżania w innych aplikacjach XML), łatwe przetwarzanie (możliwość skorzystania z interfejsu DOM). Oczywiście trzeba pamiętać o zasadach przekształcania dokumentów HTML w XHTML.

\n

DOM a (X)HTML

\n

Nie ulega wątpliwości, że na co dzień w sieci formatem XML, który wymaga najwięcej przetwarzania jest właśnie XHTML. Strony internetowe zbudowane przy pomocy XHTML-a można przetwarzać standardowymi metodami udostępnianymi przez DOM. Jednak nie jest to zbyt wygodne - większość elementów posiada bardzo specyficzne własności. Dla języka XHTML stworzono dlatego specjalne rozszerzenie interfejsu DOM (jego implementacje działają zazwyczaj również z dokumentami HTML) - opisuje ono dodatkowe metody elementów definiowanych przez XHTML pozwalając na bardzo łatwe manipulowanie stronami chociażby przy tworzeniu aplikacji webowych w technologii AJAX.

\n

Technologie XML

\n

XML daje ogromne możliwości. Być może nawet nie wiesz jak szeroko jest on używany w dzisiejszym oprogramowaniu. Jego prostota i elastyczność sprawiają, że idealnie nadaje się na przykład jako format do protokołów sieciowych. Przedstawię tutaj tylko wybrane z różnych dziedzin przykładu użycia XML-a. Na co dzień jest on używany w przeróżnych celach i znajomość jego to praktycznie podstawa w dziedzinie przetwarzania danych.

\n

SVG

\n

Jest to format (którego użyłem w tym artykule jako przykład) grafiki wektorowej. Grafika wektorowa ma tę zaletę, że jest zapisywana w postaci matematycznej, dzięki temu można ją przeskalować do dowolnej wielkości bez utraty jakości ani informacji. SVG to otwarty standard, a dzięki temu, że jest oparty na XML-u można łatwo generować obrazy SVG w programach. Nadaje się bardzo dobrze do tworzenia wszelkiego rodzaju schematów i wykresów, gdzie dane powinno się dać łatwo zmienić, jednak można go z powodzeniem używać do dowolnego innego rodzaju grafik.

\n

SOAP

\n

SOAP to protokół typu RPC - Remote Procedure Call. Daje on możliwość przesyłania wywołań procedur przez sieć, oraz odbierania rezultatów takich zapytań. W rezultacie można tworzyć aplikacje korzystające z serwera za pośrednictwem wygodnego interfejsu programistycznego wyglądającego jak zwykłe wywołania biblioteczne. Przykładem jest chociażby opisywane przeze mnie Allegro WebAPI.

\n

Jabber

\n

Jabber to oparty na XML, uniwersalny i elastyczny protokół komunikacyjny. Wykorzystywany jest przede wszystkim w komunikatorach internetowych (dzięki obsłudze \"transportów\" daje możliwość korzystania także z innych sieci jako usług serwera). Korzystają z niego między innymi polskie AQQ, czy Tlen.

\n

ODF, OOXML

\n

Niewiele osób zdaje sobie sprawę, że obecnie większość popularnych formatów biurowych również korzysta z XML-a. OpenDocument (ODF) to format używany przez pakiet OpenOffice.org. Jest to oficjalny międzynarodowy standard ISO. Z kolei mało kto z korzystających na co dzień z najnowszej wersji MS Office wie, że Microsoft również do swoich dokumentów używa formatów opartych na XML-u. Format ten nazywa się OOXML i również jest standardem ISO.

\n

Bardzo prosto można się o tym przekonać, wystarczy zmienić rozszerzenie pliku któregokolwiek z tych formatów na .zip - pliki te są po prostu archiwami ZIP zawierającymi dokumenty XML.

\n

XML 1.1

\n

Opisywana przeze mnie tutaj wersja XML-a to 1.0. Istnieje również wersja 1.1. Na pierwszy rzut oka niewiele się zmieniło i ogólne zasady nadal są takie same. Jednak zmiana wersji niesie kilka zmian, które powodują, że nie każdy poprawny dokument XML 1.0 jest poprawnym dokumentem XML 1.1 i to sprawia, że nowa wersja nie zdobywa na razie popularności - tak na prawdę nie wnosi ona zbyt wiele, więc nie ma po co zmieniać wszystkiego i narażać się na niekompatybilność ze starszymi wersjami dokumentów.

\n

Podstawowa zmiana to filozofia dopuszczalnych nazw - w przypadki wersji 1.0 wszystko co nie było dozwolone było zakazane. W przypadku wersji 1.1 wszystko co nie jest zabronione jest dozwolone. Pozwala to na przykład na użycie wielu dodatkowych znaków Unicode. Oprócz tego zmieniła się filozofia dotycząca wielu znaków kontrolnych - wiele znaków, których nie można było używać poprzednio, teraz można używać w tekście za pomocą encji (jednak nadal nie można używać znaku #0, nawet jako encji). Jednak z drugiej strony wiele znaków kontrolnych, które można było używać bezpośrednio, teraz trzeba przekształcać na encje, co właśnie powoduje problemy.

\n

Ogólnie, jeśli nie potrzebujemy, to nie ma żadnej realnej potrzeby przenoszenia się na nowszą wersję - nie jest to żadna rewolucja, a jedynie zmiany wprowadzone (niestety) po czasie.

\n

Na koniec

\n

Podsumowując, jeśli mamy zamiar obsługiwać i przetwarzać dokumenty za pośrednictwem sieci, praktycznie na pewno zetkniemy się z XML-em. A jeśli już musimy z nim pracować to warto go dobrze znać. Brak podstawowej wiedzy na temat jego działania prowadzi często do wypaczonego podejścia, a XML nie jest wcale trudny, więc dobrze jest poświęcić chwil kilka na zgłębienie jego przynajmniej podstawowych mechanizmów.

","publishedAt":"2009-03-30T01:17:33Z","view":"views/sites/display/blog.xhtml","url":null,"commentingEnabled":true,"category":{"name":"Blog","slug":"blog","view":"views/sites/list/blog.xhtml","siteView":"views/sites/display/blog.xhtml"},"tags":[{"name":"Web","slug":"web"},{"name":"Technologie","slug":"technologie"},{"name":"Teksty","slug":"teksty"},{"name":"XML","slug":"xml"}]}],"total":61,"current":7,"pageSize":6,"category":{"name":"Blog","slug":"blog","view":"views/sites/list/blog.xhtml","siteView":"views/sites/display/blog.xhtml"}} }; require("moment/locale/pl"); //]]>
Rafał Wrzeszcz - Wrzasq.pl

Przegląd frameworków JavaScript: jQuery

Thursday, 11 June 2009, 15:33

Muszę przyznać, że dojo wywarło na mnie bardzo pozytywne wrażenie, mimo kilku mankamentów dotyczących raczej mojego subiektywnego podejścia i metod tworzenia aplikacji. Następny postanowiłem wypróbować jQuery. Ten framework cieszy się dużą popularnością i bardzo szybko zdobywa sobie uznanie w sieci. Powiem szczerze, że opinie, jakie o nim czytałem w większości niemal spowodowały, że w ciemno wybrałbym ten framework - od razu powiem, że całe szczęście, że postanowiłem to wszystko przejść na własnej skórze. Ta biblioteka rozczarowała mnie i to mocno. Zupełnie nie rozumiem fascynacji nią w środowisku deweloperów. Jedyną jej zaletą jest to, że pozwala stworzyć tasiemca w jednej linijce, który coś zrobi.

Tags: Web, Teksty, JavaScript, AJAX, DOM

» Komentarze

Przegląd frameworków JavaScript: dojo

Wednesday, 10 June 2009, 03:51

JavaScript jest obowiązkowym elementem każdej nowoczesnej aplikacji webowej. Ja sam jestem w nim powiedzmy średnio-zaawansowany: tego co jest potrafię używać do czego potrzeba, ale poezji w nim nie stworzę. We własnych aplikacjach piszę kod dość łopatologicznie, natomiast kiedy tworzę coś, co musi zadziałać i to sprawnie, wykorzystuję framework, do którego akurat jest dostępne przystępne case study projektów podobnych do tego, co właśnie muszę wyposażyć w interfejs wygodniejszy niż czysty XHTML+CSS. Jednak z czasem stało się to niewygodne, bo zamiast przyzwyczajać się chociaż do jednego frameworka, za każdym razem zaczynałem pracę od nowa. Postanowiłem wstawić w swój silnik webowy jakiś konkretny framework. Postanowiłem przejrzeć 4 popularne frameworki - dojo, jQuery, MooTools i Prototype. Początkowo brałem też pod uwagę YUI, jednak po przejrzeniu dokumentacji i przykładów doszedłem do wniosku, że jest on nieadekwatny do moich potrzeb. To czego potrzebowałem nie jest tam wcale uproszczone (na przykład brak wsparcia dla przesyłania danych za pośrednictwem XHR wykorzystując JSON, a sam framework jest niewątpliwie stworzony z myślą o wysoce skalowalnych, dużych serwisach - ja JavaScript wykorzystuję na mniejszą skalę. Postanowiłem się więc podzielić swoimi spostrzeżeniami na temat wspomnianych bibliotek. Nie będą to tutoriale, ale moje subiektywne oceny, może pomogą komuś w podjęciu decyzji.

Tags: Web, Teksty, JavaScript, AJAX, DOM

» Komentarze

Mapy Google na swojej stronie

Friday, 05 June 2009, 06:12

Wielu z Was pewnie nieraz widziało na przeróżnych stronach zamieszczone mapki Google'a jako interaktywne wstawki. Ba, nawet pokazujące miejsce, o którym akurat strona traktuje. Umieszczenie takiej mapki na stronie wcale nie jest trudne, a wręcz banalnie proste - wszystko dzięki rozbudowanemu API udostępnionemu przez Google. Google Maps API począwszy od wersji 2 dostępne jest za pośrednictwem standardowego interfejsu JavaScript udostępnianego przez Google. Obecnie w wersji testowej jest już trzecia wersja API do map, jednak ja opiszę tutaj obecnie dostępną jako stabilną wersję drugą, zresztą nie sądzę, aby w podstawowych wywołaniach zaszły diametralne zmiany. Zanim jednak zaczniemy pracę musimy wygenerować sobie klucz dostępu. W tym cely musimy się udać na stronę rejestracji i podać URL strony, na której chcemy używać map. Tutaj od razu uwaga - wpisujemy taki adres, po jakim będą na stronę wchodzić użytkownicy. Google nie sprawdza IP, hosta, ani niczego innego związanego z połączeniem - jedynie URL jaki został wpisany w przeglądarce. Oznacza to, że jeśli mamy skrypt dostępny pod kilkoma domenami, to musimy wstawiać odpowiednie klucze dla każdej domeny. Z drugiej strony, nawet jeśli pracujemy na tymczasowej domenie, albo wręcz w testowym środowisku, nie będzie potem potrzeby zmiany klucza. Mając klucz możemy przejść do kwestii technicznych. Opiszę tutaj jedynie podstawy korzystania z Google Maps API, szczegółową dokumentację znajdziecie tutaj.

Tags: Web, JavaScript, Tutorial, Google

» Komentarze

Ciekawostka o okładce Red Alert 3

Monday, 11 May 2009, 20:37

Generalnie nie gram w gry. Primo nie mam na to czasu, secundo nie kręcą mnie w sumie, tertio szczerze mówiąc obecnie wychodzi tyle chłamu, że nawet nie warto się dotykać za większość tych kaszanowatych kopii starych przebojów z obciętą grywalnością nastawionych na fajerwerkową grafikę. Ale jest kilka serii, z tych, które istnieją do dziś, które darzę sentymentem (nawet jeśli kolejne części są coraz gorsze). Jedną z takich serii jest Command & Conquer. Jej ostatnią odsłoną jest Red Alert 3 (a nawet jest już do niego dodatek - Uprising). Nie grałem w niego przede wszystkim ze względu na brak czasu, oraz drugie przede wszystkim ze względu na niewystarczający sprzęt (dlaczego już nikt nie robi gier, które mieszczą się na flopce i wystarcza im kilka kB RAMu? :(). Niemniej po zakupie, bądź co bądź chyba bardziej z przyzwyczajenia, niż w celu rozkoszowania się przesłodzoną grafiką, dodatku jakoś tak otworzyłem pudełko od podstawki i zauważyłem pewną ciekawostkę, którą wam zaprezentuję, bo chyba niewielu w ferworze walki z przeciwnikiem to zauważyło, a że ja grać nie miałem jeszcze okazji, to przynajmniej pudełko trochę przestudiowałem - otóż jeśli komuś nie pasuje komunistyczna propaganda na domyślnej okładce może ją sobie zmienić!

Tags: Ciekawostki, Gry, Rozrywka

» Komentarze

SVN w praktyce

Thursday, 23 April 2009, 02:04

Na początku zawsze jest chaos. Brak jakiegokolwiek planu działania, porządku, schematów - tylko wolność i swoboda. Tak zaczyna chyba każdy, kto w domowym zaciszu próbuje stawiać pierwsze kroki w programowaniu. Nie ma potrzeby, żeby programy dzielić na kilka plików, kod mający kilkadziesiąt, góra kilkaset linijek to już tasiemiec - kompiluje się go w ułamku sekundy i sprawdza czy działa; jeśli nie to patrzy dlaczego, jeśli tak to sprawdza, dlaczego tak, a nie inaczej. Zazwyczaj całe środowisko pracy to sam notatnik (wiem, że nie każdy używa Windows, ja pierwsze programy pisałem pod Linuksem i Amiga Workbench, ale przejmijmy, że to synonim "prostego edytora tekstu"). Z czasem jednak wszystko się rozwija - zaczyna się tworzyć coraz bardziej złożone rzeczy, notatnik zastępuje się IDE, odkrywa się, że zamiast wypisywać w każdej linijce śledzoną zmienną, można posłużyć się debuggerem. Ale wraz ze wzrostem złożoności tworzonych projektów trudniejsze jest nie tylko ich rozwijanie, ale również utrzymywanie - zaczyna się zauważać, jak wiele czynności staje się żmudnych i czasochłonnych. Zaczyna się pracować z innymi ludźmi i zachodzi potrzeba kontroli nad kodem (oraz innymi elementami projektów). Jednym z najbardziej pomocnych narzędzi zarówno przy samodzielnym grzebaniu w jakimś bardziej złożonym oprogramowaniu, jak i w pracy w zespole jest system kontroli wersji.

Tags: Subversion, Praca, Tutorial, Organizacja, Projekty

» Komentarze

Od podstaw: XML

Monday, 30 March 2009, 01:17

XML to "rozszerzalny język znaczników" (ang. eXtensible Markup Language). Oznacza to, że jest to język uniwersalny przeznaczony do tworzenia języków oznaczeń - sam w sobie jest jedynie zbiorem zasad składni, definiuje pewne mechanizmy rządzące dokumentem, nie definiuje za to żadnych znaczników ani atrybutów. Innymi słowy XML określa jedynie format zapisu, a nie format samych danych. Robią to dopiero języki oparte na XML-u takie jak XHTML, RSS i wiele innych. Sam XML jest pochodnym SGML, a ten z kolei wywodzi się z GML. Nie będę ich tutaj omawiał, jednak ich idea jest podobna. Zostały one opracowane w celu przechowywania i współdzielenia dokumentów w jednolity sposób na przestrzeni lat. XML jest w gruncie rzeczy uproszczoną wersją SGML - ogranicza jego implementacje tylko do domyślnej składni, ujednolica wiele zagadnień (jak chociażby "puste" tagi). O XML-u pewnie obiło się wielu osobą o uszy, często jednak nie zdają sobie sprawy jak ważne są niektóre jego aspekty. Widać to chociażby w przypadku stron WWW tworzonych w tej technologii (korzystając z języka XHTML).

Tags: Web, Technologie, Teksty, XML

» Komentarze