Błędy podczas ustawiania tablicy opcje_bitowe w web-api dla moto.gratka.pl.

18 lipca 2010

W wyniku rozbieżności w implementacji protokołu SOAP przez platformy php a .net element opcje_bitowe w web-api dla moto.gratka.pl nie jest prawidłowo odczytywany.

Najprostszym rozwiązaniem jest dodanie do obiektu  obsługującego połączenie metody __doRequest(), która wyłapie odpowiednie fragmenty kodu XML odpowiedzialne za przesył tablicy i przetransformuje ją przed wysłaniem na serwer do postaci, która będzie czytelna dla platformy .net:

1
2
3
4
5
6
7
8
9
10
11
12
13
class myGratkaSoap extends SoapClient{

function __doRequest( $request, $location, $action, $version,  one_way=0 ) {
//PATCH for 'opcje_bitowe'. Transform element to the form accepted by .NET soap server.

$request = preg_replace( '-<opcje_bitowe.*opcje_bitowe">-', '<opcje_bitowe xsi:type="urn:opcje_bitowe" soapenc:arrayType="xsd:int[]">', $request );

return parent::__doRequest( $request, $location, $action, $version );
}

...

}

Wywoływanie metod klas wywiedzionych z poziomu klas bazowych.

12 czerwca 2010

Ponieważ metody nie mają specjalnych uprawnień przy wywyływaniu metod z tego samego obiektu, metoda, wywoływana z klasy bazowej, która wywyłuje inną metodę z klasy bazowej, może w rezultacie wywołać metodę z klasy wywiedzionej. Ilustruje to poniższy przykład w języku Python:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/python
# -*- coding: utf-8 -*-

class Istota:
  def sensIstnienia( self ):
    print( ' - Rozmnarzać się. ' )

class Zwierzę( Istota ):
  def sensIstnienia( self ):
    Istota.sensIstnienia( self )
    print( ' - Jeść, Spać. ' )
    self.powiedzCos()
  def powiedzCos( self ):
    return
class Człowiek( Zwierzę ):
  def przywitajSię( self ):
    print( 'witam' )
    self.programuj()

  def sensIstnienia( self ):
    Zwierzę.sensIstnienia( self )
    print( ' - Zaspokajać potrzby wyższego rzędu. ' )
  def powiedzCos( self ):
    return 'Myślę więc jestem'
  # Potrzebne jedynie Człowiekowi,
  # Programista nie potrzebuje tej metody
  # ma swoją!
  def programuj( self ):
    print( ':( Nie potrafię.' )

class Papuga( Zwierzę ):
  def powiedzCos( self ):
    return 'Daj ziarenko'

class Programista( Człowiek ):
  def sensIstnienia( self ):
    Zwierzę.sensIstnienia( self )
    print( ' - Programować. ' )
  def programuj( self ):
    print( ':) programuję!' )

print('*** Człowiek ***')
cypek = Człowiek()
cypek.programuj()

print('*** Programista ***')
zenek = Programista()
zenek.sensIstnienia()
print( zenek.powiedzCos() )
zenek.przywitajSię()

print('*** Papuga ***')
kakadu = Papuga()
kakadu.sensIstnienia()
print( kakadu.powiedzCos() )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
*** Człowiek ***
:( Nie potrafię.

*** Programista ***
- Rozmnarzać się.
- Jeść, Spać.
- Programować.
Myślę więc jestem
witam
:) programuję!

*** Papuga ***
- Rozmnarzać się.
- Jeść, Spać.
Daj ziarenko

Metoda programuj(), jest potrzebna jedynie przy wywoływaniu obiektu Człowiek, dla obiektu Programista nie jest ona potrzebna. Wywołujemy na obiekcie zenek metodę przywitaj się, Programista jako taki nie potrafi się przywitać ale ponieważ jest człowiekiem, klasa Człowiek dostarcza implementacji dla przywitaj().
Jesteśmy więc teraz na poziomie klasy człowiek.
Metoda przywitaj() wywołuje metodę programuj(), której z kolei Człowiek mógłby nie posiadać ( posiada ją jedynie aby prawidłowo obsłużyć wcześniejsze wywołanie obiektu cypek ) Programista ją posiada więc wyołana zostanie jego metoda, która w tym wypadku nadpisuje metodę programuj() klasy Człowiek. (a która była by jedyna gdyby człowiek nie posiadał metody programuj())

Anonimowe klasy wewnętrzne w Java

7 czerwca 2010

Jeżeli wewnętrzna klasa (local class jest użyta tylko raz można zaimplementować ją jako klasę anonimową. W ten sposób definicja i użycie klasy następuje w tym samym miejscu.

Poniższy przykład pokazuje klasę wewnętrzną:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Phone {

  class Screen{
    private String color;
    public void displayMessage(){
      System.out.println("Screen is black!");
    }
  }

  public Screen screen(){
    return new Screen();
  }

  public static void main(String[] args) {
    Phone nokia1112 = new Phone();
    Screen nokiaScreen = nokia1112.screen();
    nokiaScreen.displayMessage();
  }
}

Poniższy przykład pokazuje klasę anonimową adekwatną do przykładu wyżej.
Warto zauważyć że bezpośrednio po wywołaniu utworzeniu klasy obiekt wynikający z klasy jest rzutowany na typ (w tym przypadku na interface Screen). W praktyce oznacza to że nie ma możliwości dodawania nowych metod w klasie anonimowej. Możliwe jest jedynie implementowanie interfejsów lub nadpisywanie (overloading) metod klas na które obiekt klasy anonimowej jest rzutowany.

W przypadku przekazywania parametru dla klasy anonimowej typ na który jest rzutowany obiekt z klasy anonimowej musi posiadać odpowiedni konstruktor.
Jeżeli rzutujemy na interfejs to mamy do dyspozycji jedynie domyślny konstruktor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
interface Screen{
void displayMessage();
};</em>

<em>public class Phone {</em>

<em> public Screen screen(){
return new Screen(){
public String color;
public void displayMessage(){
System.out.println("Screen is black!");
}
public String toString(){
return "XXX";
}
};
}</em>

<em> public static void main(String[] args) {
Phone nokia1112 = new Phone();
Screen nokiaScreen = nokia1112.screen();
nokiaScreen.displayMessage();
}
}

Parametr inicjalizowany w funkcji anonimowej musi być finalny.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Outer {
class Screen{
void displayMessage(){}
};</em>

<em>public class Phone {
public Screen screen(final String color){
return new Screen(){
private String screenColor = color;
public void displayMessage(){
System.out.println("Screen is black!");
}
public String toString(){
return "kolor to: " + screenColor;
}
};
}</em>

<em> public static void main(String[] args) {
Phone nokia1112 = new Phone();
Screen nokiaScreen = nokia1112.screen("zielony");
nokiaScreen.displayMessage();
System.out.println( nokiaScreen );
}
}

Klasy anonimowe nie mogą deklarować swoich konstruktorów, nie mają nazwy. Mogą jednak korzystać z konstruktorów klas na które są rzutowane.

Wykorzystanie konstruktora z klasy bazowej finale nie jest potrzebne ponieważ zmienna w klasie anonimowej nie jest inicjalizowana.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Screen{
void displayMessage(){}
void Screen(String screenColor){}
};</em>

<em>public class Phone {
public Screen screen(String color){
return new Screen(){
//private String screenColor = color;
public void displayMessage(){
System.out.println("Screen is black!");
}
public String toString(){
return "jabadabadu!";
}
};
}</em>

<em> public static void main(String[] args) {
Phone nokia1112 = new Phone();
Screen nokiaScreen = nokia1112.screen("zielony");
nokiaScreen.displayMessage();
System.out.println( nokiaScreen );
}
}

Klasy zagnieżdżone w Java

3 czerwca 2010

Klasy zagnieżdżone są to klasy, które mogą posiadać zmienne i metody statyczne. Zwykłe klasy wewnętrzne nie ich posiadać  ponieważ nie są elementami najwyższego poziomu, odwołanie do nich jest wykonywane przez obiekt klasy zewnętrznej a nie przez klasę.

Z powyższego wynika też, że nie jest możliwe odwoływanie się do klasy zewnętrznej z poziomu klasy statyczniej (brak this).

Nazwa klasy zagnieżdżonej umieszczonej w klasie zewnętrznej powinna być poprzedzona słowem static.
Obiekt klasy statycznej można tworzyć bez odnoszenia się do obiektu klasy zewnętrznej.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Komputer {
  static String hardDrive = "hitashi";

  static public Procesor procesor(Integer iloscRdzeni){
    return new Procesor(iloscRdzeni);
  }

  static public class Procesor{
    static Integer iloscRdzeni;

    Procesor(Integer iloscRdzeni){
      this.iloscRdzeni = iloscRdzeni;
    }
    public String toString(){
      return hardDrive;
    }
  }
}

Klasy umieszczane wewnątrz interfejsów stają się  automatycznie klasami statycznymi.

Wzorzec projektowy obserwator (observer)

3 czerwca 2010

Wzorzec projektowy obserwator

Obiekt powiadamia inne obiekty o zmianie swojego stanu. Obiekty te muszą wcześniej wyrazić zainteresowanie, czyli zarejestrować się do obiektu publikującego informację o zmianie swojego stanu.

Wydawca (publisher) – Obiekt  do którego rejestrują się obiekty zainteresowane jego stanem.

Abonent (observer) – Obiekt zainteresowany  stanem wydawcy.

Udziałowiec – Wprowadza mechanizmy obsługi otrzymywanych powiadomień.

Warto zwrócic uwage, że na różnicę pomiędzy wydawcą a abonentem. Programiści poznający wzorzec, często mylnie określają obiekt Wydawcy mianem Obserwatora. Prawdopodobnie lepszą nazwą dla wzorca był by „Wydawca”. Podmiotem bowiem jest właśnie wydawca a nie obiekty abonentów (obserwatory).

Observer.php

1
2
3
4
interface Observer{
  public function notify( Observable $publisher,
    $eventType );
}

Observable.php

1
2
3
4
5
Interface Observable{
  public function addObserver( Observer $observer,
    $eventType );
  public function fireEvent( $eventType );
}

Publisher.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Wydawca
class Publisher implements Observable{
  private $observers = array();
  private $name = "Publisher";
  public function getName()
  {
    return $this->name;
  }
 
  public function addObserver( Observer $observer,
    <$eventType )
  {
    $this->observers[$eventType][] = $observer;
  }
 
  public function fireEvent( $eventType )
  {
    foreach( $this->observers[$eventType] as
      $observer )
    {
      $observer->notify( $this, $eventType );
    }  
  }
}

ObserverB.php

1
2
3
4
5
6
7
8
9
10
// Abonent
class ObserverB implements Observer{
  public function notify( Observable $object,
    $argument )
  {
    echo '<br />' . $object->getName() .
      ' powiadamia obiekt typu ' . __CLASS__ .
      ' i przekazuje mu parametr: ' . $argument;
  }
}

ObserverA.php

1
2
3
4
5
6
7
8
9
class ObserverA implements Observer{
  public function notify( Observable $object,
    $argument )
  {
    echo '<br />' . $object->getName() .
      ' powiadamia obiekt typu ' . __CLASS__ .
      ' i przekazuje mu parametr: ' . $argument;
  }
}

index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
include_once( 'Observable.php' );
include_once( 'Observer.php' );
include_once( 'ObserverA.php' );
include_once( 'ObserverB.php' );
include_once( 'Publisher.php' );

$observer1 = new ObserverA();
$observer2 = new ObserverA();
$observer3 = new ObserverA();
$observer4 = new ObserverB();
$observer5 = new ObserverA();

$publisher = new Publisher();
$publisher->addObserver( $observer1,
  'wydarzenie_jeden' );
$publisher->addObserver( $observer2,
  'wydarzenie_dwa' );
$publisher->addObserver( $observer3,
  'wydarzenie_trzy' );
$publisher->addObserver( $observer4,
  'wydarzenie_dwa' );
$publisher->addObserver( $observer5,
  'wydarzenie_dwa' );

echo '<br />**** Odpalenie: wydarzenie_dwa ****';
$publisher->fireEvent( 'wydarzenie_dwa' );
echo '<br />**** Odpalenie: wydarzenie_jeden ****';
$publisher->fireEvent( 'wydarzenie_jeden' );
echo '<br />**** Odpalenie: wydarzenie_trzy ****';
$publisher->fireEvent( 'wydarzenie_trzy' );

Wyjście:

1
2
3
4
5
6
7
8
9
10
11
12
13
**** Odpalenie: wydarzenie_dwa ****
Publisher powiadamia obiekt typu ObserverA
i przekazuje mu parametr: wydarzenie_dwa
Publisher powiadamia obiekt typu ObserverB
i przekazuje mu parametr: wydarzenie_dwa
Publisher powiadamia obiekt typu ObserverA
i przekazuje mu parametr: wydarzenie_dwa
**** Odpalenie: wydarzenie_jeden ****
Publisher powiadamia obiekt typu ObserverA
i przekazuje mu parametr: wydarzenie_jeden
**** Odpalenie: wydarzenie_trzy ****
Publisher powiadamia obiekt typu ObserverA
i przekazuje mu parametr: wydarzenie_trzy

Klasy wewnętrzne w Java.

2 czerwca 2010

Każda klasa wewnętrzna może niezależnie dziedziczyć implementację. A zatem klasy wewnętrzne nie są ograniczone przez to, że klasy zewnętrzne dziedziczą już jakąś implementację. Pozwala to uwolnić fragment kodu  od zbędnej implementacji przy zachowaniu zwięzłego zapisu.

Klasy wewnętrzne umożliwiają wielokrotne dziedziczenie implementacji. Efektywnie umożliwiają dziedziczenie po więcej niż jednej rzeczy nie będącej interfejsem.

Klasy wewnętrzne uzyskujemy poprzez umieszczenie klasy w klasie :P
Klasy wewnętrzne nie mogą posiadać statycznych pól ani metod.

Z reguły w kodzie klasy zewnętrznej występuje metoda zwracająca referencje do klasy wewnętrznej. Aby utworzyć obiekt klasy wewnętrznej poza klasą zewnętrzną, konieczne jest odwołanie się do klasy zewnętrznej:

1
NazwaKlasyZewnętrznej.NazwaKlasyWewnętrznej

Przykład prostej klaswy wewnętrznej:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Outer{
  public class Inner{
    public Inner(){
      //Klasa wewnętrzna ma dostęp do klasy zewnętrznej.
      System.out.println( kubek );
      //Odwołanie do klasy zewnętrznej jako takiej
      System.out.println( Outer.this);
    }
  }
  public String kubek = "Czerwnoy kubek";
  public Inner getInner(){
    Inner obiektWewnetrzny = new Inner();
    return obiektWewnetrzny;
  }

  public static void main(String[] args) {
    //Obiekt klasy zewnętrznej
    Outer obiekt = new Outer();
    //Tworzenie 'ręczne' obiektu klasy wewnętrznej
    Inner obiektWewnetrzny2 = obiekt.new Inner();
    //Pobieranie obiektu poprzez metodę
    Outer.Inner obiektWewnetrzny3 = obiekt.getInner();
  }

  public String toString(){
    return " To jest klasa która ma: " + kubek;
  }
}

Aby wygenerować w klasie wewnętrznej referencje do obiektu klasy zewnętrznej należy użyć:

1
nazwaKlasyZewnętrznej.this

samo this odnosiło by się do klasy wewnętrznej.

Przy tworzeniu obiektu klasy wewnętrznej koniczne jest posiadanie egzemplarza klasy zewnętrznej, którego nazwa powinna poprzedzać operator new.

1
obiekt.new Inner()

Obiekty java-script (Literały obiektowe)

1 czerwca 2010

Literały obiektowe (Object Literals) sa najprostszym sposobem na utworzenie obiektu w java-script.

1
2
3
4
5
6
7
//obiekt pustyDom
var pustyDom = {};
//obiekt ludek
var ludek = {
  "first-name": "Lesny",
  "last-name": "Ludek"
}

Obiekty mogą zawierać się w sobie wzajemnie (nested objects)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var pociag = {
  name: "Krakus",
  numer: 815,
  odjazd: {
    miasto: "Krakow",
    time: "2011-09-22 14:55",
    stacja: 1
  },
  przyjazd: {
    miasto: "Warszawa",
    time: "2011-09-22 18:42",
    stacja: 2
  }
};

Operatory && oraz || pomagają w zachowaniu czytelności kodu.

1
2
3
4
5
6
7
8
9
10
11
var obiekt = {
// znak - jest nie dozwolony konieczne
// jest więc użycie cudzysłowów
'samolot-bialy': "Mewa",
};
// || może być użyte do nadania domyślnej wartości
console.log(obiekt.wodolot.costam || 'xx');
// && chroni przed użyciem
// niezdefiniowanych zmiennych (undefined)
console.log(obiekt.rakieta &&
  obiekt.rakieta.costam);<br>

console.log() – metoda wypisująca zawartość na konsole działa dla firefox z dodatkiem firebug
var – nadaje zmiennym charakter lokalny, zmienne nie poprzedzone tym słowem mają charakter globalny co jest niepożądane.

MySQL Tworzenie nowego użytkownika.

31 maja 2010

Poleceniem GRANT można utworzyć nowego użytkownika.

Tworzenie użytkownika z uprawnieniami roota (prawidłowe jedynie dla developingu)

1
2
3
GRANT ALL PRIVILEGES ON *.* TO 'dbuser'@'%'

IDENTIFIED BY 'dbpass'  WITH GRANT OPTION;

MySQL Tworzenie nowej bazy z kodowaniem utf8.

29 maja 2010

Aby utworzyć nową bazę dla MySQL z ustawionym kodowaniem UTF8:

1
CREATE DATABASE dbname CHARACTER SET UTF8;

MySQL Ustawienie wartości rozpoczynającej autoinkrementacje.

29 maja 2010

Poniższe polecenie ustawia licznik autoinkrementacji – dla pola z kluczem typu autoincrement – na wskazaną wartość.

1
ALTER TABLE dbtable AUTO_INCREMENT = 1000;