2008.11_Spring 2 Schema _[Projektowanie XML].pdf
(
505 KB
)
Pobierz
441732201 UNPDF
XML
Spring 2 Schema
Własne przestrzenie nazw w Spring 2.x
Ten artykuł wprowadzi Cię szybko w podstawowe techniki tworzenia
własnych przestrzeni nazw XML Schema dla plików konfiguracyjnych
Spring IOC. Autorzy Spring Framework pisząc o dobrym oprogramowaniu
promują zasadę DRY (Don't Repeat Yourself) – wyraźnie widać to w
mechanizmie rozszerzania konfiguracji XML kontenera Springa.
Dowiesz się:
• Jak za pomocą własnej przestrzeni nazw XML
stworzyć najprostsze rozszerzenia składni pli-
ków koniguracyjnych XML dla Spring Frame-
work w wersji 2.x.
Powinieneś wiedzieć:
• Podstawowa znajomość języka Java oraz kon-
iguracja kontenera Inversion Of Control dla
Spring Framework 2.x za pomocą plików XML;
• Wskazana jest również minimalna wiedza z za-
kresu języka XML oraz API programowej ob-
sługi kontenera Spring IOC.
rzyć. Zaliczyć do nich należy głównie usprawnio-
ne uzupełnianie składni w edytorach XML do-
stępnych w popularnych IDE oraz zestaw dodat-
kowych przestrzeni nazw włączonych do dystry-
bucji Springa począwszy do wersji 2.0. W szcze-
gólności predefiniowane przestrzenie nazw oka-
zują się być przydatne w codziennej pracy – po-
zwalają one m.in. na zastąpienie rozbudowanych
definicji fabryk typu FieldRetrievingFactoryBean,
ListFactoryBean lub TransactionProxyFactoryBe-
an ich kompaktowymi odpowiednikami wyrażo-
nymi za pomocą określonej przestrzeni nazw.
Twórcy Springa nie poprzestali na szczęście
na dostarczeniu nam zestawu predefiniowa-
nych przestrzeni nazw, ale udostępnili również
mechanizm do samodzielnego tworzenia tych-
że. Nie muszę chyba wspominać o tym jak bar-
dzo konfiguracja naszej aplikacji zyska na czy-
telności po zastosowaniu elementów oraz atry-
butów własnej konstrukcji, dostosowanych do
Poziom trudności
w dalszym ciągu działają w wersji 2.0 Springa (ze
względu na słynne umiłowanie kompatybilności
wstecz przez jego autorów), jakkolwiek zalecaną
formą konfiguracji XML jest teraz XML Schema.
(
Inversion Of Control
) dla języka Java. Ofe-
ruje on kilka sposobów konfiguracji apli-
kacji oraz wstrzykiwania zależności, jednak naj-
bardziej popularną techniką uzyskiwania tych ce-
lów jest konfiguracja w pliku XML. Jak powszech-
nie wiadomo XML oferuje czytelną, hierarchiczną
strukturą prezentowanych przez siebie informa-
cji, które to m.in. zapewniły mu rolę niepisanego
standardu konfiguracji aplikacji webowych. XML
jednakże cechuje się również tendencją do
gadatli-
wości
tzn. do konieczności opisywania zawartych
w nim danych za pomocą dużej ilości tekstu. Pro-
gramiści używający Springa w wersji niższej niż
2.0 skazani byli na używanie dość ograniczonego
zestawu narzędzi redukujących rozmiar plików
konfiguracyjnych XML oraz zjawiska tzw.
XML
hell
(np. stosowanie dziedziczenia definicji be-
anów lub automatycznego wiązania). Na szczęście
twórcy Springa od wersji 2.0 swojego frameworka
dodali możliwość konfiguracji aplikacji za pomocą
plików XML zdefiniowanych nie tylko zgodnie z
DTD, ale i mechanizmem XML Schema. Oczywi-
ście stare konfiguracje napisane pod kątem DTD
Motywacja
Nie trzeba nawet specjalnie zachęcać do stoso-
wania nowej definicji plików konfiguracyjnych
XML, gdyż oferuje nam ona rozliczne korzyści
o których użytkownicy DTD mogą tylko poma-
Listing 1.
Szkielet koniguracji kontenera Springa oparty na XML DTD
<!-- Stara koniguracja -->
<
?xml version=
"1.0"
encoding=
"UTF-8"
?
>
<
!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd"
>
<
beans
>
<
/beans
>
Listing 2.
Szkielet koniguracji kontenera Springa oparty na XML Schema
<!-- Nowa koniguracja -->
<
?xml version=
"1.0"
encoding=
"UTF-8"
?
>
<
beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"
http://www.springframework.org/schema/beans http://www.springframework.org/schema/
beans/spring-beans-2.0.xsd"
>
<
/beans
>
52
11/2008
S
pring jest popularnym frameworkiem IOC
Spring 2 Schema
naszych konkretnych potrzeb. Zysk ten będzie
widoczny w szczególności jeżeli planujemy
wielokrotne wykorzystywanie naszego kodu w
aplikacjach używających np. pisanej przez nas
biblioteki. W artykule tym chciałbym właśnie
przedstawić podstawowe techniki rozszerzania
możliwości konfiguracyjnych XML w Springu.
Listing 3.
Przykład użycia komponentu z własnej przestrzeni nazw
<
?xml version=
"1.0"
encoding=
"UTF-8"
?
>
<
beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:myns=
"http://www.foo.com/customSchema"
xsi:schemaLocation=
"
http://www.springframework.org/schema/beans http://www.springframework.org/schema/
beans/spring-beans-2.0.xsd
http://www.foo.com/customSchema http://www.foo.com/customSchema.xsd"
>
Migracja
na nowy styl konfiguracji
Przejście na nowy styl konfiguracji jest bardzo
proste. Wystarczy zamienić w istniejących pli-
kach konfiguracyjnych parę pierwszych linijek
dokumentu.
Migracja zaprezentowana na Listingu 2 jest
niemalże bezbolesna. Niemalże, gdyż istnieje
parę (dosłownie parę) szczegółów konfigura-
cji które zostały uznane przez twórców Sprin-
ga za przestarzałe (deprecated) i które należy w
związku z tym dostosować do nowej konfigura-
cji opartej na XML Schema. Do szczegółów te-
go typu należy np. atrybut
singleton
elemen-
tu
<bean>
, który w nowej konfiguracji powi-
nien zostać zamieniony na atrybut
scope
(ze
względu na wprowadzenie mechanizmu roz-
szerzalnych zasięgów w nowszych wersjach
Springa).
<
myns:bar id=
"bar"
value=
"barValue"
/
>
<
/beans
>
Listing 4.
Kod przykładowego komponentu Bar
package foo;
public class Bar {
// wartość komponentu
private String value;
public Bar(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}
Witaj przestrzenio
– przypadek użycia
Na początku spróbujemy napisać jak najszyb-
ciej najprostszą przestrzeń nazw z jednym ele-
mentem. Na potrzeby przykładów minimal-
nych zawartych w tym artykule załóżmy, że
pracujemy dla firmy Foo i naszym zadaniem
jest stworzenie elementu XML który pozwo-
li nam na bardziej efektywne używanie kom-
ponentu
Bar
w aplikacjach korzystających ze
sprzedawanej przez nas biblioteki. Wyobraźmy
sobie, że docelowo nasz klient chciałby konfi-
gurować swoją aplikację za pomocą komponen-
tu
Bar
w następujący sposób – Listing 3.
Oczekujemy, że powyższa konfiguracja utwo-
rzy w kontenerze instancję klasy
Bar
o
id
rów-
nym
bar
oraz wartości prywatnej właściwości
value
równej
barValue
. Sam komponent
Bar
wygląda następująco – Listing 4.
Listing 5.
Dokument XML Schema deiniujący przykładową przestrzeń
<
?xml version=
"1.0"
encoding=
"UTF-8"
?
>
<
xsd:schema xmlns=
"http://www.foo.com/customSchema"
xmlns:xsd=
"http://www.w3.org/2001/XMLSchema"
xmlns:beans=
"http://www.springframework.org/schema/beans"
targetNamespace=
"http://www.foo.com/customSchema"
elementFormDefault=
"qualiied"
attributeFormDefault=
"unqualiied"
>
<
xsd:import namespace=
"http://www.springframework.org/schema/beans"
/
>
<
xsd:element name=
"bar"
>
<
xsd:complexType
>
<
xsd:complexContent
>
<
xsd:extension base=
"beans:identiiedType"
>
<
xsd:attribute name=
"value"
type=
"xsd:string"
use=
"required"
/
>
<
/xsd:extension
>
<
/xsd:complexContent
>
<
/xsd:complexType
>
<
/xsd:element
>
<
/xsd:schema
>
Schemat kroków
Klasyczny schemat kroków wykonywany podczas
tworzenia własnej przestrzeni nazw to kolejno:
• napisanie dokumentu XSD;
• stworzenie parserów dla nowych elemen-
tów lub atrybutów XML;
• zaprogramowanie własnej klasy typu
NamespaceHandler
, która pozwoli nam na
zmapowanie parserów i dekoratorów do
określonych elementów i atrybutów XML;
• dodanie do wynikowej aplikacji lub biblio-
teki meta-danych potrzebnych Springowi.
W Sieci
•
http://springframework.org
– Strona projektu Spring Framework
•
http://static.springframework.org/spring/docs/2.5.x/api
– Spring 2.5 API
•
http://static.springframework.org/spring/docs/2.5.x/reference/xsd-conig.html –
Koniguracja
oparta na XML Schema w Spring 2.5
•
http://static.springframework.org/spring/docs/2.5.x/reference/extensible-xml.html –
Własna prze-
strzeń nazw wg Spring 2.5 Reference
•
http://www.w3.org/XML/Schema
– XML Schema
•
http://www.w3.org/ – DOM
XMl DOM
W kolejnych sekcjach opiszę szerzej każdy z
tych kroków.
www.sdjournal.org
53
XML
Dokument XSD
Dokument XML Schema pozwoli nam określić
składnię naszej przestrzeni nazw, czyli m.in. ja-
kie elementy oraz atrybuty są w niej dopusz-
czalne, a jakie nie. Schema uwzględnia również
informacje o tym jakie typy danych zawarte są
w poszczególnych elementach i atrybutach na-
szej przestrzeni oraz czy są one obowiązkowe.
Interesujący nas schemat mógłby mieć następu-
jącą postać – Listing 5.
Tematyka tworzenia definicji XML Schema
jest poza zakresem tego artykułu. Ograniczę się
zatem do podsumowania, że zdefiniowaliśmy
właśnie element o nazwie
bar
zawierający jeden
(wymagany) atrybut o nazwie
value
. Element
ten dziedziczy również po identyfikowalnym
typie Springa, co w praktyce oznaczna tyle, że
również
implicite
dziedziczy atrybut
id
. Na-
stępnym krokiem zbliżającym nas do działającej
przestrzeni nazw będzie zmapowanie elementu
XML zdefiniowanego powyżej do Javy.
Listing 6.
Przykładowy parser komponentu Bar
package foo;
import org.springframework.beans.factory.support.BeanDeinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDeinitionParser;
import org.w3c.dom.Element;
public class BarParser extends AbstractSingleBeanDeinitionParser {
@Override
// Oczekujemy instancji klasy Bar
protected Class
<
Bar
>
getBeanClass(Element element) {
return Bar.class;
}
@Override
protected void doParse(Element element, BeanDeinitionBuilder builder) {
// Odczytaj wartość atrybutu
String value = element.getAttribute("value");
// i dodaj ją jako argument konstruktora wynikowej instancji
builder.addConstructorArgValue(value);
}
}
Parser elementu
Aby przekonwertować element XML do instan-
cji zarejestrowanej w kontenerze musimy napi-
sać parser implementujący interfejs
org.spring
framework.beans.factory.xml.BeanDefiniti
onParser
. Klasy implementujące wspomniane-
go interfejsu służą do analizy pojedynczego ele-
mentu XML znajdującego się bezpośrednio mię-
dzy elementami
<beans></beans>
, wraz z ew.
podelementami znajdującymi się wewnątrz na-
szej definicji. Nasz konkretny element
<bar>
jest
raczej prosty tzn. nie zawiera zagnieżdżonych
elementów i zwróci tylko jedną instancję (klasy
Bar
) do rejestracji w kontrolerze. Ograniczmy się
zatem do dziedziczenia z klasy
AbstractSingle
BeanDefinitionParser
– Listing 6.
Klasa
BeanDefinitionBuilder
jest jedną z
najważniejszych klas programowej obsługi kon-
tenera Springa.
Temat ten zasługuje na co najmniej parę
osobnych artykułów, tak więc ograniczę się tyl-
ko do podania informacji, że klasa ta służy do
programowego tworzenia instancji klasy prze-
znaczonej do rejestracji w kontenerze. W tym
konkretnym przykładzie chcemy, aby nowy
obiekt klasy
Bar
został stworzony za pomocą
jednoargumentowego konstruktora.
Listing 7.
Handler mapujący przykładowy element 'bar' do wybranego parsera
package foo;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class BarNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
// zarejestruj instancję parsera dla
// elementów
<bar/>
z tej przestrzeni nazw
registerBeanDeinitionParser("bar", new BarParser());
}
}
Listing 8.
Zawartość pliku META-INF/spring.handlers
http\://www.foo.com/customSchema=foo.BarNamespaceHandler
Listing 9.
Zawartość pliku META-INF/spring.schema
http\://www.foo.com/customSchema.xsd=foo/foo.xsd
Listing 10.
Kod minimalnego komponentu 'Bar' rozszerzonego o listę swoich potomków
package foo;
import java.util.List;
public class Bar {
private String value;
private List
<
Bar
>
children;
public Bar(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
public void setChildren(List
<
Bar
>
children) {
this.children = children;
}
public List
<
Bar
>
getChildren() {
return children;
}
}
Zarejestrowanie
elementu w NamespaceHandler
Instancje interfejsu
org.springframework.bean
s.factory.xml.NamespaceHandler
służą do łą-
czenia przestrzeni nazw z parserami elementów
oraz atrybutów XML. Sam
NamespaceHandler
nie wykonuje logiki związanej z analizą elemen-
tów i atrybutów XML, ponieważ całą logikę
związaną z czytaniem dokumentu XML zawar-
liśmy w poprzednim kroku (w definicji parse-
ra).
NamespaceHandler
oferuje parę metod po-
zwalających na interakcję z nim w określonych
momentach jego cyklu życia, jakkolwiek na na-
sze skromne potrzeby zainteresujemy się jedynie
bezargumentową metodą
init()
wywoływaną
w momencie inicjalizacji handlera.
W powyższym przykładzie (Listing 7) zma-
powaliśmy parser napisany w poprzednim
kroku do elementu XML
<bar>
. W miażdżą-
cej większości przypadków jeden handler bę-
54
11/2008
Spring 2 Schema
dzie mapował wiele parserów i/lub dekorato-
rów –nie implementujemy wielu handlerów
dla jednej przestrzeni nazw. Jak wspomnia-
łem wcześniej nasze potrzeby względem han-
dlera są bardzo skromne – dlatego właśnie
dziedziczymy z klasy
org.springframework.
beans.factory.xml.NamespaceHandlerSupp
ort
. Dzięki wspomnianej klasie pomocniczej
możemy nadpisać metodę
init()
interfejsu
oraz nie martwić się o logikę związaną z reje-
stracją parsera.
Listing 11.
Przykład użycia zagnieżdżonego komponentu
<
myns:bar id=
"bar"
value=
"parent"
>
<
myns:bar value=
"child1"
>
<
myns:bar value=
"grandChild"
/
>
<
/myns:bar
>
<
myns:bar value=
"child2"
/
>
<
/myns:bar
>
Listing 12.
Uaktualniony dokument XML Schema uwzględniający zagnieżdżanie elementów
<
?xml version=
"1.0"
encoding=
"UTF-8"
?
>
<
xsd:schema xmlns=
"http://www.foo.com/customSchema"
xmlns:xsd=
"http://www.w3.org/2001/XMLSchema"
targetNamespace=
"http://www.foo.com/customSchema"
elementFormDefault=
"qualiied"
attributeFormDefault=
"unqualiied"
>
Meta-dane dla Springa
Ostatnim krokiem jest dodanie do korzenia
ścieżki klas naszej aplikacji lub biblioteki fol-
deru META-INF wraz z plikami
spring.handlers
oraz
spring.schemas
– Listing 8 i Listing 9.
Jak widać pierwszy z nich mapuje URI prze-
strzeni nazw na napisany przez nas wcześniej
handler – tą metodą Spring wie których par-
serów powinien użyć dla poszczególnych ele-
mentów i atrybutów w określonej przestrzeni
nazw. Drugi zaś wskazuje fizyczną lokalizację
pliku XSD z definicją naszej przestrzeni – w
tym konkretnym przypadku plik z definicją po-
winien znajdować się w pakiecie
foo
i nazywać
się
foo.xsd
. Pragę zwrócić uwagę na koniecz-
ność poprzedzania znaków dwukropka w oby-
dwu plikach znakiem
backslash
(ze względu na
fakt, że nie tylko znak równości, ale i dwukro-
pek są poprawnymi symbolami końca klucza w
plikach właściwości Javy).
<
xsd:element name=
"bar"
>
<
xsd:complexType
>
<
xsd:choice minOccurs=
"0"
maxOccurs=
"unbounded"
>
<
xsd:element ref=
"bar"
/
>
<
/xsd:choice
>
<
xsd:attribute name=
"id"
type=
"xsd:ID"
/
>
<
xsd:attribute name=
"value"
use=
"required"
type=
"xsd:string"
/
>
<
/xsd:complexType
>
<
/xsd:element
>
<
/xsd:schema
>
Listing 13.
Parser elementu 'bar' uwzględniający rekurencję
package foo;
import java.util.List;
import org.springframework.beans.factory.support.AbstractBeanDeinition;
import org.springframework.beans.factory.support.BeanDeinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.AbstractBeanDeinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
public class BarParser extends AbstractBeanDeinitionParser {
Zagnieżdżanie elementów
– rozszerzony przypadek użycia
Powyższy przykład jest nieco prosty, gdyż za-
kłada że sparsowany element XMLa zareje-
struje tylko jedną instancję określonej klasy w
kontrolerze. Jeżeli chcielibyśmy rekurencyjnie
parsować i rejestrować zagnieżdżone elemen-
ty XML powinniśmy stworzyć parser dziedzi-
czący po czymś potężniejszym niż
AbstractSi
ngleBeanDefinitionParser
– tą klasą jest np.
AbstractBeanDefinitionParser
. Wyobraź-
my sobie, że nasz przypadek użycia rozszerzy-
my w następujący sposób – otóż nasz potężny
komponent
Bar
został rozszerzony o listę swo-
ich
dzieci
(dla uproszczenia przykładu również
instancji klasy
Bar
) – Listing 10.
Przykładowy scenariusz konfiguracji drzewa
komponentów
Bar
w pliku XML mógłby wy-
glądać następująco – Listing 11.
Powyższa zmiana konfiguracji pociąga za so-
bą oczywiście konieczność aktualizacji doku-
mentu XML Schema – Listing 12.
Poza schematem XML w stosunku do po-
przedniego przykładu zmianie uległby w zasa-
dzie tylko sam parser – Listing 13.
Powyższy parser mógłby dziedziczyć po kla-
sie
AbstractSingleBeanDefinitionParser
i
dalej zwracać wynik zgodny z zadanym scena-
riuszem, jakkolwiek dziedziczenie po
Abstrac
tBeanDefinitionParser
pozwala na jego nie-
co czytelniejszą implementację.
protected AbstractBeanDeinition parseInternal(Element element,
ParserContext parserContext) {
// Stwórz budowniczego deinicji elementu
BeanDeinitionBuilder barBuilder = BeanDeinitionBuilder
.rootBeanDeinition(Bar.class);
barBuilder.addConstructorArgValue(element.getAttribute("value"));
// Wyszukanie dzieci elementu określonego typu
List
<
Element
>
childElements = DomUtils.getChildElementsByTagName(
element, "bar");
if (childElements != null) {
// Dodanie potomków do listy zarządzanej przez kontener
ManagedList children = new ManagedList(childElements.size());
for (Element e : childElements) {
// Rekurencja
children.add(parseInternal(e, parserContext));
}
barBuilder.addPropertyValue("children", children);
}
return barBuilder.getBeanDeinition();
}
}
www.sdjournal.org
55
XML
Własne atrybuty
– przypadek użycia
Ostatnim istotnym przypadkiem użycia jest
dodanie własnego atrybutu do dowolnego ele-
mentu w pliku konfiguracyjnym – Listing 14.
Załóżmy, że chcemy aby podczas parsowania
elementu oznaczonego atrybutem
myns:bar
(o dowolnej wartości) na konsoli pojawiała się
wartość licznika wskazującego ile elementów
oznaczonych identyczną wartością znaleziono
dotychczas w kontenerze.
Listing 14.
Przykład użycia atrybutu XML z własnej przestrzeni nazw
<
bean class=
"java.lang.String"
myns:bar=
"barValue"
>
<
constructor-arg value=
"someValue"
/
>
<
/bean
>
Zmiany w implementacji
Jak łatwo się domyśleć na pierwszy ogień pój-
dzie aktualizacja schematu XML – Listing 15.
Podobnie jak w przypadku własnych ele-
mentów, dla nowego atrybutu również musi-
my napisać własny parser. Możemy to wygod-
nie zrobić poprzez implementację interfejsu
BeanDefinitionDecorator
– Listing 16.
Tym razem będziemy również musieli zmo-
dyfikować
BarNamespaceHandler
.
Wynika to z faktu, iż tym razem nie rejestru-
jemy parsera definicji
beana
, a tylko tzw. deko-
rator, czyli mniejszy parser służący do mody-
fikacji lub wzbogacania wybranego fragmen-
tu definicji. Oczywiście wyświetlanie informa-
cji o tym którą z kolei definicję oznaczoną kon-
kretną wartością parsuje kontener, jest w real-
nym świecie średnio przydatne, jakkolwiek do-
stęp do parametrów
BeanDefinitionHolder
oraz
ParserContext
daje nam możliwość ma-
nipulacji kolejno definicją dekorowanego ele-
mentu (możemy również zwrócić całkowicie
nową instancję zamiast modyfikować istnie-
jącą) oraz całym rejestrem kontenera. Nieste-
ty ze względu na ograniczony rozmiar niniej-
szego artykułu jestem zmuszony przemilczeć
szczegóły dotyczące możliwości programowej
manipulacji definicjami beanów oraz zawarto-
ścią kontenera.
Listing 15.
Dokument XML Schema dla minimalnego atrybutu
<
?xml version=
"1.0"
encoding=
"UTF-8"
?
>
<
xsd:schema xmlns=
"http://www.foo.com/customSchema"
xmlns:xsd=
"http://www.w3.org/2001/XMLSchema"
targetNamespace=
"http://www.foo.com/customSchema"
elementFormDefault=
"qualiied"
attributeFormDefault=
"unqualiied"
>
<
xsd:attribute name=
"bar"
type=
"xsd:string"
/
>
<
/xsd:schema
>
Listing 16.
Parser minimalnego atrybutu z własnej przestrzeni
package foo;
import java.util.HashMap;
import org.springframework.beans.factory.conig.BeanDeinitionHolder;
import org.springframework.beans.factory.xml.BeanDeinitionDecorator;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Attr;
import org.w3c.dom.Node;
public class BarParser implements BeanDeinitionDecorator {
HashMap
<
String, Integer
>
counters = new HashMap
<
String, Integer
>
();
@Override
public BeanDeinitionHolder decorate(Node node,
BeanDeinitionHolder holder, ParserContext ctx) {
// odczytaj wartość atrybutu
String value = ((Attr) node).getValue();
// sprawdź wartość licznika
Integer i = counters.get(value);
if (i == null) {
i = 0;
}
// zwiększ licznik
counters.put(value, ++i);
// wyświetl wynik
System.out.println(value + ": " + i);
return holder;
}
}
Podsumowanie
W niniejszym artykule poznaliśmy podsta-
wowe sposoby rozszerzania możliwości kon-
figuracyjnych plików XML w Springu za po-
mocą własnych przestrzeni nazw. Znając spo-
soby na analizę elementów XML najwyższe-
go poziomu (wraz z ich ew. zagniżdżenia-
mi) oraz atrybutów XML możemy rozpocząć
tworzenie własnych przestrzeni nazw, któ-
re przy minimalnej znajomości XML DOM
oraz API programowej manipulacji zawar-
tością kontenera IOC Springa pozwolą nam
na napisanie w pełni funkcjonalnych mapo-
wań dla naszych komponentów. Tematyka
tego artykułu powinna w szczególności za-
interesować osoby dostarczające dla innych
firm programistycznych gotowe rozwiąza-
nia oparte na Springu ze względu na zmini-
malizowanie wiedzy wymaganej przez klien-
ta do poprawnego stosowania naszych kom-
ponentów.
Listing 17.
Handler mapujący parser do atrybutu 'bar'
package foo;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class BarNamespaceHandler extends NamespaceHandlerSupport {
HENRYK KONSEK
Autor pracuje na stanowisku projektanta JEE w
warszawskiej irmie Artegence. Udziela się rów-
nież jako administrator serwisu javablackbelt.com.
W wolnym czasie interesuje się swoją Anią oraz
m.in. psychiatrią oraz dobrymi technologiami.
Kontakt z autorem: http://www.hekonsek.pl lub he-
konsek@gmail.com.
@Override
public void init() {
registerBeanDeinitionDecoratorForAttribute("bar", new BarParser());
}
}
56
11/2008
Plik z chomika:
Kapy97
Inne pliki z tego folderu:
2006.03_Aplikacje w modelu aktówki _[Projektowanie XML].pdf
(781 KB)
2006.03_Współpraca Zope i Mozilli – generowanie XUL przy wykorzystaniu Zope_[Projektowanie XML].pdf
(785 KB)
2006.03_LINQ – C# 3.0_[Projektowanie XML].pdf
(627 KB)
2008.11_Spring 2 Schema _[Projektowanie XML].pdf
(505 KB)
2008.08_OOXML _[Projektowanie XML].pdf
(993 KB)
Inne foldery tego chomika:
Algorytmy
Antyhaking
Aplikacje Biznesowe
Aspekty
Bazy Danych
Zgłoś jeśli
naruszono regulamin