Suunnitteludokumentti

Ohjelmistotuotantoprojekti TAHKO (syksy 2001)

Heikki Hiltunen

Tero Kallio

Anu Leponiemi

Piia Porvali

Petri Savolainen

Janne Savukoski


Sisällys

1. Yleistä
1.1. Ohjelmiston kuvaus
1.2. Tärkeimmät vaatimukset
2. Osajärjestelmien yleiskuvaus
2.1. Kaaviokuva osajärjestelmistä ja sen selitys
2.2. Osajärjestelmien välinen kommunikointi ja protokollat
2.3. Rinnakkaisuusasiat
3. Www-käyttöliittymä
3.1. Yleistä
3.2. Sisäänkirjautuminen
3.3. Asiakkaan haku
3.4. Asiakkaan valinta
3.5. Tuotteen haku
3.6. Tuotteen valinta
3.7. Tuotteiden hinnoittelu
3.8. Vapaamuotoinen teksti
3.9. Voimassaoloajan määrittely
3.10. Uusi tarjous
3.11. Tarjouksen haku
3.12. Tarjouksen valinta
3.13. Vaihda asiakas
3.14. Poista tuote listasta
3.15. Talleta tarjous
3.16. Näytä PDF
4. Filtteri
4.1. Yleistä
4.2. Kaaviokuva ulkoisista ja sisäisistä olioista
4.3. Rajapinnat toisiin osajärjestelmiin
4.4. XMLFilter
4.4.1. Toimintosuunnitelma
4.5. DependencyFilter
4.5.1. Toimintosuunnitelma
4.6. ProductItem (implements Item)
4.6.1. Tietosuunnitelma
4.6.2. Toimintosuunnitelma
4.7. ProductFactory
4.7.1. Toimintosuunnitelma
4.8. DependencyFactory
4.8.1. Toimintosuunnitelma
4.9. Item (interface)
4.10. DependencyRule
4.10.1. Tietosuunnitelma
4.10.2. Toimintosuunnitelma
4.11. DependencyCore
4.11.1. Toimintosuunnitelma
4.12. ItemNode
4.12.1. Tietosuunnitelma
4.12.2. Toimintosuunnitelma
5. Tietokanta
5.1. DBSlave
5.2. Kaaviokuva ulkoisista ja sisäisistä olioista ja sen selitys
5.3. Rajapinnan kuvaus toisiin osajärjestelmiin
5.4. Rajapinnan kuvaus ulkoisiin elementteihin
5.4.1. DBSlave
5.4.2. DBResult
5.5. DBSlave:n luokkakuvaus
5.5.1. Tietosuunnitelma
5.5.2. Toimintosuunnitelma
6. Servlet
6.1. Yleiskuvaus
6.2. TahkoServlet
6.2.1. Liittymäsuunnitelma
6.2.2. Toimintosuunnitelma
7. ApacheWrapper
7.1. ApacheWrapper
7.2. FopWrapper
7.2.1. Liittymäsuunnitelma
7.2.2. Toimintosuunnitelma
7.3. XmlProcessor
7.3.1. Liittymäsuunnitelma
7.3.2. Toimintosuunnitelma
7.4. TomcatWrapper
7.4.1. Tietosuunnitelma
7.4.2. Liittymäsuunnitelma
7.4.3. Toimintosuunnitelma
8. Profiili
8.1. Yleiskuvaus
8.2. Profile (interface)
8.2.1. Liittymäsuunnitelma
8.3. ItemElement (interface)
8.3.1. Liittymäsuunnitelma
8.4. MyItemElement
8.4.1. Tietosuunnitelma
8.4.2. Liittymäsuunnitelma (Item- ja ItemElement-rajapintoihin kuulumattomat metodit)
8.4.3. Toimintosuunnitelma (vain konstruktori, muut metodit triviaaleja)
9. Muuta

Luku 1. Yleistä

1.1. Ohjelmiston kuvaus

Tarjouskonfiguraattori (TAHKO) on Sonera Oyj:n myyjille tuotettava tarjousdokumenttien generointiohjelmisto. Ohjelmisto toteutetaan Helsingin yliopiston tietojenkäsittelytieteen laitoksen ohjelmistotuotantoprojektina. Ohjelmistolla generoidaan tarjousdokumentteja käyttäjän antamien tietojen pohjalta. Ohjelman tarkoituksena on helpottaa myyjien työtä ja saada tarjouksista ulkoasultaan yhteneviä.

1.2. Tärkeimmät vaatimukset

Ohjelmistoa käytetään www-selaimen avulla ja se vaatii käynnistyäkseen hyväksyttävän tunnuksen ja salasanan. Tarjousta tehtäessä valitaan asiakas ja tuotteet, joita asiakkaalle aiotaan tarjota. Käyttäjä voi muokata tuotteiden hintoja määrätyissä rajoissa. Asiakas ja tuotetiedot tulevat tietokannasta. Lisäksi tietokannassa säilytetään tarjousdokumenttien ulkoasun määrääviä tiedostoja. Annettujen tietojen perusteella TAHKO generoi halutun muotoisia tarjousdokumentteja. Dokumentit voidaan tulostaa erilaisissa formaateissa (esim. PDF) ja ne voidaan tallentaa tietokantaan XML-muodossa, josta ne saadaan uudelleen muokattaviksi ja tulostettaviksi.

Luku 2. Osajärjestelmien yleiskuvaus

2.1. Kaaviokuva osajärjestelmistä ja sen selitys

Kuva 2.1: Osajärjestelmät

Tahkossa on kuusi osajärjestelmää (kuva 2.1): WWW-käyttöliittymä, Filteri, ApacheWrapper, Tietokanta, Servlet ja Profile. Www-käyttöliittymällä tarkoitetaan käyttäjän www-selaimessa näkyvää TAHKO:n osaa. Servlet on www-palvelimella ajettava Java-ohjelma, joka toimii välittäjänä käyttöliittymän ja muun TAHKO:n välillä. Tietokantaoperaatiot hoidetaan TAHKO:ssa JDBC:tä käyttävän Tietokanta-osajärjestelmän avulla, joka toimii yksinkertaistettuna Java-rajapintana relaatiotietokantaan. ApacheWrapper on yksinkertaistettu rajapinta Apachen XML- ja JSP-työkaluille. Filter-osajärjestelmä suodattaa tietokannasta tulevaa tietoa tuotteiden väliset riippuvuussuhteet huomioivaksi. Profiili-osajärjestelmä huolehtii sessionhalinnasta käyttäjän tehdessä tarjousta TAHKO:lla. Profiili-osajärjestelmä tallettaa käyttäjän tekemät asiakas- ja tuotevalinnat xml-muodossa käyttösession ajaksi. Tarkemmat kuvaukset kunkin osajärjestelmän suunnitelmista on kuvattu seuraavissa luvuissa (luvut 3-8).

2.2. Osajärjestelmien välinen kommunikointi ja protokollat

Www-käyttöliittymä kommunikoi servletin kanssa käyttäen http-protokollaa. Muu osajärjestelmien välinen kommunikointi tapahtuu paikallisina Java-metodikutsuina (kuva 2.2).

Kuva 2.2: Sekvenssikaavio

2.3. Rinnakkaisuusasiat

Apachen Tomcat huolehtii rinnakkaisten http-pyyntöjen käsittelystä. Rinnakkaisuuteen ei tarvitse TAHKO:a toteuttaessa kiinnittää huomiota.

Luku 3. Www-käyttöliittymä

3.1. Yleistä

Ohjelman käyttäjälle näkyvä käyttöliittymä on toteutettu XML:llä sisäänkirjautumista lukuunottamatta. Seuraavissa aliluvuissa on kuvattu käyttöliittymän eri vaiheet ja niihin liittyvä XML.

3.2. Sisäänkirjautuminen

Sisäänkirjautumisikkunassa (kuva 3.1) käyttäjä antaa käyttäjätunnuksen ja salasanan päästäkseen järjestelmään. Sivulta lähtevät parametrit ovat käsittelevän sivun id (page=0), käyttäjätunnus (user_login) ja salasana (user_password). Onnistuneen sisäänkirjautumisen tuloksena siirrytään asiakkaan hakuun (kuva 3.2). JSP:ltä saadaan seuraavat asiat:

Vasenkehys:
Hakukentän luontiin tarvittava XML.

Oikea kehys:

Tämänhetkinen tarjouksen tilanne. Käyttäjän tiedot selvillä.


<offer>
 <element name=user>
    <field name=firstname>DATA</field>
    <field name=lastname>DATA</field>
    <field name=department>DATA</field> 
    <field name=street>DATA</field>
    <field name=area>DATA</field>
    <field name=city>DATA</field>
    <field name=country>DATA</field>
    <field name=phone>DATA</field>
    <field name=fax>DATA</field>
    <field name=email>DATA</field>
  </element>
</offer>

Virheellinen salasana tai käyttäjätunnus palauttaa käyttäjän takaisin sisäänkirjautumissivulle (kuva 3.1).

Kuva 3.1: Sisäänkirjautuminen.

Kuva 3.2: Myyjä kirjautunut sisään järjestelmään.

3.3. Asiakkaan haku

Asiakkaan haku ikkunassa (kuva 3.2) käyttäjä voi hakea asiakkaita yrityksen tai yhteyshenkilön mukaan. Sivulta lähtevät parametrit ovat käsittelevän sivun id (page=1), hakusana (search) ja hakukategoria (category). Haku palauttaa listan kaikista hakuehdon täyttävistä asiakkaista (kuva 3.3). JSP:ltä saadaan seuraavat asiat:

Vasen kehys:
Hakukentän luontiin tarvittava XML ja suoritetun haun tulos.


<data>
 <db_result table=customer>
  <records>
   <record>
    <column name=id>DATA</column> 
    <column name=company>DATA</column>
    <column name=department>DATA</column> 
    <column name=firstname>DATA</column>
    <column name=lastname>DATA</column>
    <column name=phone>DATA</column>
    <column name=street>DATA</column>
    <column name=area>DATA</column>
    <column name=city>DATA</column>
    <column name=country>DATA</column>
    <column name=fax>DATA</column>
    <column name=email>DATA</column>
   </record>
   <record>
    ...
   </record>
  </records>
 </table>
</data>


tai jos haussa ei löydy mitään

<data>
 <db_result name=customer>
  <no_records_found />
 </db_result>
</data>

Kuva 3.3: Asiakashaun tulos.

Kuva 3.4: Asiakashaussa ei löytynyt yhtään asiakasta.

3.4. Asiakkaan valinta

Asiakashaun tuloksena saadusta listasta (kuva 3.3) valitaan haluttu asiakas painamalla Valitse-linkkiä. Jos haussa ei löytänyt yhtään asiakasta se kerrotaan käyttäjälle (kuva 3.4). Sivulta lähtevät parametrit ovat käsittelevän sivun id (page=2) ja asiakas id (customer_id). Kun asiakas on valittu siirrytään tuotteiden valinta sivulle (kuva 3.5) JSP:ltä saadaan seuraavat asiat:

Vasen kehys:
Tuotteiden hakukenttä.


Oikea kehys:
<offer>
  <element name=user>
    <field name=firstname>DATA</field>
    <field name=lastname>DATA</field>
    <field name=department>DATA</field> 
    <field name=street>DATA</field>
    <field name=area>DATA</field>
    <field name=city>DATA</field>
    <field name=country>DATA</field>
    <field name=phone>DATA</field>
    <field name=fax>DATA</field>
    <field name=email>DATA</field>
  </element>

  <element name=customer>
    <column name=id>DATA</column> 
    <column name=company>DATA</column>
    <column name=department>DATA</column> 
    <column name=firstname>DATA</column>
    <column name=lastname>DATA</column>
    <column name=phone>DATA</column>
    <column name=street>DATA</column>
    <column name=area>DATA</column>
    <column name=city>DATA</column>
    <column name=country>DATA</column>
    <column name=fax>DATA</column>
    <column name=email>DATA</column>
  </element>
</offer>

Kuva 3.5: Asiakas valittu.

3.5. Tuotteen haku

Tuotteen haku ikkunassa (kuva 3.5) käyttäjä voi hakea tuotteita niiden nimen tai id:n mukaan. Sivulta lähtevät parametrit ovat käsittelevän sivun id (page=3), hakusana (search) ja hakukategoria (category). Haku palauttaa listan kaikista hakuehdon täyttävistä tuotteista (kuva 3.6). JSP:ltä saadaan seuraavat asiat:

Vasen kehys:
Hakukentän luontiin tarvittava XML ja haun tulos


<data>
 <db_result table=product>
  <records>
   <record>
    <selectable type=(Y|N|M)/>
    <column name=id>DATA</column> 
    <column name=name>DATA</column> 
    <column name=group>DATA</column> 
    <column name=description>DATA</column> 
    <column name=min_price>DATA</column> 
    <column name=price_currency>DATA</column>
   </record>
   <record>
    ...
   </record>
  </records>
 </db_result>
</data>
  

tai jos haussa ei löydy mitään

<data>
 <db_result table=product>

  <no_records_found />
 </db_result>
</data>

  

Kuva 3.6: Tuotehaun tulos.

Kuva 3.7: Tuotehaussa ei löytynyt yhtään tuotetta.

3.6. Tuotteen valinta

Tuotehaun tuloksena saadusta listasta (kuva 3.6) valitaan haluttu tuote painamalla Valitse-linkkiä. Linkin painamisesta seuraa myös vasemman kehyksen uudelleenlataus. Jos haussa ei löytänyt yhtään tuotetta se kerrotaan käyttäjälle (kuva 3.7). Sivulta lähtevä parametrit ovat käsittelevän sivun id (page=4) tuote id (product_id). JSP:ltä saadaan seuraavat asiat:

Vasen kehys:
Hakukenttä


Oikea kehys:
<offer>
  <element name=user>
    <field name=firstname>DATA</field>
    <field name=lastname>DATA</field>
    <field name=department>DATA</field> 
    <field name=street>DATA</field>
    <field name=area>DATA</field>
    <field name=city>DATA</field>
    <field name=country>DATA</field>
    <field name=phone>DATA</field>
    <field name=fax>DATA</field>
    <field name=email>DATA</field>
  </element>
  

  <element name=customer>
    <column name=id>DATA</column> 
    <column name=company>DATA</column>
    <column name=department>DATA</column> 
    <column name=firstname>DATA</column>
    <column name=lastname>DATA</column>
    <column name=phone>DATA</column>
    <column name=street>DATA</column>
    <column name=area>DATA</column>
    <column name=city>DATA</column>
    <column name=country>DATA</column>
    <column name=fax>DATA</column>
    <column name=email>DATA</column>
  </element>
  

  <element name=product>
    <field name=id>DATA</field> 
    <field name=name>DATA</field> 
    <field name=group>DATA</field> 
    <field name=description>DATA</field>
    <field name=min_price>DATA</field>
    <field name=units>DATA</field>
    <field name=price>DATA</field>
    <field name=price_currency>DATA</field>
  </element>
</offer>
  

Kuva 3.8: Tuote valittu.

3.7. Tuotteiden hinnoittelu

Tuotteiden hinnoittelu tapahtuu siten, että valittujen tuotteiden listassa (kuva 3.8) määritellään tuotteiden kappalemäärä ja yksikköhinta. Lisäksi käyttäjä voi määritellä alennusprosentin tarjoukselle. Jotta tuotteille määritellyt hinnat saadaan pysymään tallessa, pitää ne saada tallennettua sessioon aina silloin kun tarjoukseen lisätään tai poistetaan tuotteita tai vaihdetaan asiakasta.

3.8. Vapaamuotoinen teksti

Käyttäjä voi kirjoittaa tarjoukseen vapaamuotoista tekstiä. Tämän tekstin tarkoituksena on antaa käyttäjälle mahdollisuus kertoa lisää tarjoukseen liittyvistä yksityiskohdista (kuva 3.8).

3.9. Voimassaoloajan määrittely

Käyttäjä määrittelee tarjoukselle voimassaoloajan (päivä, kuukausi ja vuosi) (kuva 3.8).

3.10. Uusi tarjous

Uusi tarjous luodaan painamalla Luo uusi tarjous -linkkiä sivun yläreunassa. Tämän jälkeen tarjouksen tiedot nollataan (paitsi myyjä). Sivulta lähtevä parametri on käsittelevän sivun id (page=5). Tilanne palautuu Asiakkaan haku -kohtaan (kuva 3.2).

3.11. Tarjouksen haku

Tallennettu tarjous avataan painamalla Avaa vanha tarjous -linkkiä, jolloin siirrytään tallennetun tarjouksen hakusivulle (kuva 3.9). Lähteväksi parametriksi asetetaan käsittelevän sivun id (page=6). Tarjousta etsitään asiakkaan nimen avulla ja mahdollisesti määritellään, kuinka uusi haettavan tarjouksen on oltava. Haussa lähtevät parametrit ovat käsittelevän sivun id (page=7), asiakkaan nimi (customer_name) ja aikaväli (how_old).

Kuva 3.9: Avaa tallennettu tarjous.

3.12. Tarjouksen valinta

Tarjoushaun tuloksena saadusta listasta valitaan haluttu tuote painamalla Valitse-linkkiä (kuva 3.6). Jos haussa ei löytänyt yhtään tuotetta, se kerrotaan käyttäjälle. Haluttu tarjous avataan painamalla Avaa-linkkiä. Lähtevät parametrit ovat käsittelevän sivun id (page=8) ja tarjouksen id (offer_id). JSP:ltä saadaan seuraavat asiat:

Oikea kehys: Hakukentän luontiin tarvittava XML ja haun tulos.


<data>
 <db_result name=offer>
  <records>
   <record>
    <field name=offer_id>DATA</field>
    <field name=contact_id>DATA</field>
    <field name=customer_id>DATA</field>
    <field name=offer_time>DATA</field>
    <field name=offer_xml>DATA</field>
   </record>
  </records>
 </db_result>
</data>
  
tai

<data>
 <db_result name=offer>
  <no_records_found>
 </db_result>
</data>
  

3.13. Vaihda asiakas

Asiakasta vaihdetaan painamalla Vaihda asiakas -linkkiä. Lähtevät parametrit ovat käsittelevän sivun id (page=9), poistettavan asiakkaan id ja kaikki tarjouksen sen hetkiset tiedot. Oikean kehyksen tilanne palautuu kohtaan asiakkaan valinta (kuva 3.2).

3.14. Poista tuote listasta

Tuote poistetaan listasta painamalla Poista-linkkiä. Lähtevä parametri on käsittelevän sivun id (page=10), poistettavan tuoteen id ja kaikki tarjouksen sen hetkiset tiedot. Saatava XML on muuten sama kuin ennen, mutta siitä puuttuu kyseinen tuote (kuva 3.5 Tuotteen valinta).

3.15. Talleta tarjous

Tarjous talletetaan painamalla Talleta-linkkiä viimeistelysivulla. Tarjous tallennetaan silloin tietokantaan offer-tauluun käyttäjän tunnuksella. Parametrina käsittelevän sivun id (page=11).

3.16. Näytä PDF

Jos tarjous halutaan tulostaa PDF:nä, painetaan Näytä PDF -linkkiä. Tällöin tarjous muutetaan PDF-muotoon, joka voidaan tulostaa. Parametrina on käsittelevän sivun id (page=12).

Luku 4. Filtteri

4.1. Yleistä

Filtteri-osajärjestelmä huolehtii tietokannasta haetun 'raakatiedon' prosessoimisesta sopivaan XML-muotoon. Varsinaisia filttereitä ovat XMLFilter ja DependencyFilter. Muut osajärjestelmään kuuluvat luokat ovat näiden käyttämiä apuluokkia (kuva 4.1).

4.2. Kaaviokuva ulkoisista ja sisäisistä olioista

Kuva 4.1: Filter-osajärjestelmä

Osajärjestelmän ulospäinnäkyvät luokat ovat DependencyFilter ja XMLFilter (kuva 4.1). DependencyFilter käyttää sisäluokkiaan ProductFactorya ja DependencyFactorya muuntamaan saamansa syötteet ProductItem- ja DependencyRule-olioksi, jotka se antaa DependencyCore-luokan käsiteltäväksi. DependencyCore käyttää apunaan sisäluokkaansa ItemNode:a.

4.3. Rajapinnat toisiin osajärjestelmiin

Osajärjestelmää käytetään XMLFilter- ja DependencyFilter-luokkien filter-metodeilla. Ne ottavat parametreina tietoa mm. DBResult-olioina ja tuottavat XML:ää.

4.4. XMLFilter

XMLFilter muuttaa DBResult-olion XML:äksi.

4.4.1. Toimintosuunnitelma


public static String filter(DBResult products)
- Muunna products XML:äksi DBResult:in toXML-metodilla
      

4.5. DependencyFilter

Prosessoi tietokannasta haettua tuotelistausta asiakkaan profiilin ja tuoteriippuvuuksien perusteella. Tuotetusta XML:ästä ilmenee, mitä tuotteita ei voida myydä asiakkaalle ja mitkä vaativat joitain toisia tuotteita. Apuna käytetään DependencyCore-luokkaa, joka selvittää riippuvuudet.

4.5.1. Toimintosuunnitelma


public String filter(DBResult products, DBResult dependencies, Profile profile, String attName)
- Muunna products ProductItem-taulukoksi ProductFactory-luokan avulla.
- Muunna dependencies DependencyRule-taulukoksi DependencyFactory-luokan avulla
- Hae profile:sta elementtejä nimellä attName
- Anna saadut taulukot DependencyCore-luokan processDependencies-metodille, joka merkitsee 
tuotelistan alkiot.
- Muuta tuotelista DOM-puuksi ja lisää tuotteisiin 'selectable'-tagi DependencyCoren 
merkintöjen mukaan.
- Muuta DOM-puu XML:äksi
      

4.6. ProductItem (implements Item)

ProductItem on DebendecyFilterin sisäluokka, jota käytetään tuotetietoja sisältävänä Item-toteutuksena.

4.6.1. Tietosuunnitelma


private Integer id; // Tunniste
private int state;  // Tila

      

4.6.2. Toimintosuunnitelma


public ProductItem(int id, int state)
- Asetetaan id ja state

public Object getId()
- Palautetaan id

public int getState()
- Palautetaan state

public void setState(int state)
- Asetetaan state
      

4.7. ProductFactory

ProductFactory on DependencyFilterin sisäluokka. Se muuttaa tuotetietoja sisältävän DBResult-olion ProductItem-taulukoksi.

4.7.1. Toimintosuunnitelma

 
public static ProductItem[] createProducts(DBResult result)
- Luodaan ProductItem-taulukko, jossa on yhtä paljon alkioita kuin result:issa on rivejä
- Käydään läpi kaikki result:in rivit ja luodaan jokaisesta ProductItem-olio taulukkoon
- Palautetaan taulukko
      

4.8. DependencyFactory

Muuttaa riippuvuustietoja sisältävän DBResult-olion DependencyRule-taulukoksi. DependencyFilterin sisäluokka.

4.8.1. Toimintosuunnitelma

 
public static DependencyRule[] createDependencies(DBResult result)
- Luodaan DependencyRule-taulukko, jossa on yhtä paljon alkioita kuin result:issa on rivejä
- Käydään läpi kaikki result:in rivit ja luodaan jokaisesta DependencyRule-olio taulukkoon
- Palautetaan taulukko
      

4.9. Item (interface)

Item on rajapintaluokka, joka määrittelee DependencyCore:lla käsiteltävien olioiden rajapinnan.

 
Tilaa (state) kuvaavat vakiot:

public static final int YES=0

public static final int NO=1

public static final int MORE=2

Metodit:

public Object getId()

public void setState(int state)
      

4.10. DependencyRule

DependencyRule kuvaa kahden tuotteen välistä riippuvuutta. Riippuvuus voi olla joko poissulkeva (exclude), tai vaativuus (include).

4.10.1. Tietosuunnitelma

 
Riippuvuuden tyyppiä kuvaavat vakiot:

public static final int TYPE_INCLUDE = 1

public static final int TYPE_EXCLUDE = 2

Tuotteiden tunnisteet:

private final Object source

private final Object target

Riippuvuuden tyyppi:

private final int type
      

4.10.2. Toimintosuunnitelma

 
public DependencyRule(Object source, Object target, int type)
   throws IllegalArgumentException
- Tarkasta, että source ja target eivät ole samat. Tuota IllegalArgumentException, jos ovat
- Tarkasta, että tyyppi on joko TYPE_EXCLUDE tai TYPE_INCLUDE. Tuota IllegalArgumentException, 
jos se on joku muu.
- Aseta source, target ja type

public Object getSource()
- Palauta source

public Object getTarget()
- Palauta target

public int getType()
- Palauta type
      

4.11. DependencyCore

Luokka merkitsee annetun Item-taulukon alkiot annettujen tuoteriippuvuuksien ja asiakkaan profiilin perusteella. Item:in tila voi olla joko YES (voi valita), NO (ei voi valita) tai MORE (vaatii lisäksi muita). Mikäli tilaksi asetetaan NO, myös kaikkien niiden Item:ien, jotka vaativat sen tilaksi asetetaan NO.

4.11.1. Toimintosuunnitelma

 
public static void processDependencies(Item[] selected,  // Profiilin tuotteet
 Item[] available, // Tuotelistaus
 DependencyRule[] dependencies)
- Käydään läpi kaikki available-taulukon alkiot ja muodostetaan jokaisesta ItemNode-olio. Oliot 
laitetaan availableItems-nimiseen Hashtableen, josta ne löytyvät helposti ID:n perusteella.
- Muodostetaan HashSet selectedIds, josta selviää nopeasti ID:n perusteella, mitkä
 Item:it löytyvät selected-taulukosta.
- Käydään säännöt (dependencies) läpi ja käsitellään ne joiden tyyppi on TYPE_INCLUDE:
 *Haetaan riippuvuuden lähde-Item availableItems-taulusta. Mikäli se löytyi,
  asetetaan sen tilaksi MORE. Mikäli myös kohde-Item on availableItems-taulussa
  lisätään lähde-Item kohde-Itemin sisältävän ItemNode olion requirers-listalle.
      
 
- Käydään säännöt uudelleen läpi ja käsitellään ne, joiden tyyppi on TYPE_EXCLUDE:
 *Jos lähde on availableItems-taulussa ja selectedIds sisältää kohteen ID:n asetetaan
  kohteen tilaksi NO. (ItemNode-luokka huolehtii siitä, että kaikkien tarvittavien
  Item:ien tilaksi asetetaan rekursiivisesti NO edellä asetettujen tarvitsemissuhteiden
  perusteella)
 *Jos kohde löytyy availableItems-taulusta ja selectedIds sisältää lähteen ID:n
  asetetaan lähteen tilaksi NO
      

4.12. ItemNode

Luokka on DependencyCoren käyttämä apuluokka, joka sisältää Itemin sekä viittaukset niihin Itemeihin, jotka tarvitsevat tätä. Näin muodostuu verkko, jonka avulla voidaan helposti asettaa rekursiivisesti Itemien tilaksi NO, kun niiden väliset (include-) riippuvuussuhteet ovat ensin tiedossa.

4.12.1. Tietosuunnitelma


Item item
int state
Vector requirers (Viitteet tarvitseviin ItemNodeihin)
      

4.12.2. Toimintosuunnitelma


public ItemNode(Item item)
- Asetetaan item
- Alustetaan tämän ItemNode:n ja sen sisältämän Item:in tilaksi YES
- Luodaan requirers-vektori

public void addRequirer(ItemNode requirer)
- Lisätään annettu ItemNode requirers-vektoriin

public void setState(int state)
- Asetetaan annettu tila sekä ItemNoden että sen sisältämän Itemin tilaksi.
- Mikäli tila on NO käydään requirers-lista läpi ja kutsutaan niillekkin setState-metodia, 
paitsi niiden kohdalla joiden tila on jo valmiiksi NO (jotta rekursio pysähtyisi myös 
syklisissä tapauksissa)
      

Luku 5. Tietokanta

5.1. DBSlave

DBSlave on TaHKo:n osajärjestelmä, joka huolehtii tietokannan käsittelystä. Tähän kuuluu tiedon haku, jossain määrin sen talletus, sekä käyttäjien autentikointi. Osajärjestelmä sisältää kirjastoluokan DBSlave ja DBResult-luokan, jota käytetään palauttaessa tietokantahakujen tuloksia. Virhetilanteissa tuotetaan DBException tai jokin sen alaluokista.

5.2. Kaaviokuva ulkoisista ja sisäisistä olioista ja sen selitys

Kuva 5.1: DBSlave

DBSlave-luokka on yhteydessä tietokantaan ja tarjoaa tietokantapalveluja muille TaHKo:n osajärjestelmille. DBResult-luokka toimii tietovarastona hakutuloksia palautettaessa. Sillä voi kysellä tiedot yksitellen tai pyytä ne XML- tai DOM-muodossa (kuva 5.1).

5.3. Rajapinnan kuvaus toisiin osajärjestelmiin

Muut osajärjestelmät käyttävät tietokanta-osajärjestelmää DBSlave-luokan julkisten metodien avulla. DBSlave palauttaa tuloksensa joko XML-muodossa (Stringinä) tai DBResult-oliona, jolloin sen sisältämiin tietoihin pääsee käsiksi DBResult-luokan julkisilla metodeilla.

5.4. Rajapinnan kuvaus ulkoisiin elementteihin

Tietokannan käsittelyyn käytetään JDBC-rajapintaa.

5.4.1. DBSlave


public static void setDBServer(String driver, String protocol, String server,
 int port, String user, String passwd,
 String db)
- Asettaa tietokantaparametrit. Tätä tulee kutsua ennen kuin varsinaisia
 tietokantaa käyttäviä metodeja voi käyttää.

public static boolean isDBServerSet()
- Onko tietokantayhteysparametrit asetettu.

public static DBResult getFromDatabase(String db, String table,
 Vector columns, String conditions,
 String orderingColumn,
 int orderingDir) throws DBException
- Hakee tavaraa tietokannasta.
    

public static String getPageLogic(String name)
    throws DBException
- Hakee sivun logiikka XML:n.

public static String getLogicXSL(String name)
    throws DBException
- Hakee logiikka XSL:n
  

public static DBResult login(String name, String password)
    throws DBException, InvalidLoginException
- Tarkastaa käyttäjän kirjautumisen ja palauttaa menestyksellisessä tapauksessa käyttäjätiedot.

public static String loadOffer(int offerId) throws DBException
- Hakee tietokantaan talletetun tarjouksen.

public static void saveOffer(String offerXML)
    throws DBException
- Tallettaa tarjouksen tietokantaan.

public static void updateOffer(int id, String offerXML)
    throws DBException
- Uudelleentallettaa tarjouksen tietokantaan.
    

5.4.2. DBResult


public int getRowCount()
- Palauttaa tuloksen rivien lukumäärän.

public int getColumnCount()
- Palauttaa tuloksen sarakkeiden lukumäärän.

public Object getObject(String columnName, int row)

public String getString(String columnName, int row)

public int    getInt(String columnName, int row)

public double getDouble(String columnName, int row)
- Palauttavat sarakkeen arvon annetulta riviltä eri muodoissa. Sarakkeeseen viitataan nimellä.
  

public Object getObject(int column, int row)

public String getString(int column, int row)

public int    getInt(int column, int row)

public double getDouble(int column, int row)
- Palauttavat sarakkeen arvon annetulta riviltä eri muodoissa. Sarakkeeseen viitataan indeksillä.

public String toXML()
- Muuntaa sisällön XML:äksi

public CoreDocumentImpl toDOM()
- Muuntaa tuloksen DOM-puuksi
  

5.5. DBSlave:n luokkakuvaus

5.5.1. Tietosuunnitelma


DBSlaven sisältämät tiedot:
dbURL    : Tietokannan URL
username : Tietokannan käyttäjätunnus
password : Tietokannan salasana
tahkoDB  : TaHKo-tietokannan nimi

DBResultin sisältämät tiedot:
tableName   : Taulun nimi, josta hakutulokset ovat peräisin
columnCount : Tuloksen sarakkeiden määrä
rowCount    : Tuloksen rivien määrä
columns     : Joukko vektoreita, jotka sisältävät tuloksen tiedot sarakkeittain
columnNames : Sarakkeiden nimet
columnTable : Hajautustaulu, joka liittää sarakkeen nimet ja niiden tiedot
              sisältävät vektorit.
   

5.5.2. Toimintosuunnitelma

Tietokannan käsittely tapahtuu kutsumalla luokan DBSlave metodeja. Vapaamuotoisia hakuja suorittava getFromDatabase-metodi palauttaa haun tulokset DBResult-oliona, jolta tiedot voidaan kysellä stringeinä, kokonaislukuina, doubleina tai objekteina tai koko tulos voidaan muuntaa XML-muotoon.

5.5.2.1. class DBSlave

DBSlave on staattinen kirjastoluokka. Ennenkuin tietokantatoimintoja voidaan käyttää, luokka täytyy alustaa kutsumalla metodia setDBServer, joka asettaa tarvittavat parameterit yhteyden saamiseksi tietokantaan.


Metodit:

public static void setDBServer(String driver, String protocol,
                               String server, int port,
                               String user, String passwd,
                       String tahkoDB)
     

Rekisteröi JDBC-ajuri
Rakenna dbURL ("jdbc:" + protocol + "://" + server + ":" + port + "/")
Aseta luokka muuttujien userName, password ja tahkoDB arvot
     

public static boolean isDBServerSet()
- Jos dbURL == null palauta false, muutoin true 

private static Connection getConnection(String db)
- return DriverManager.getConnection(dbURL + db, username, password)


public static DBResult getFromDatabase(String db, String table,
       Vector columns, String conditions,
       String orderingColumn,
       int orderingDir)
    

- Rakenna SQL-kysely:
 *SELECT:
   Jos columns == null, tulee SELECT osaan "*" (kaikki sarakkeet),
   Muutoin kaikki columns-vektorin sisältävät sarakkeennimet
   pilkuilla eroteltuina
 *FROM:
   Annettu taulun nimi table
 *WHERE:
   Jos conditions-parameteri ei ole null, lisää WHERE-osa
   annetuilla ehdoilla.
 *ORDER BY:
   Mikäli orderingColumn-parameteri on annettu, lisää ORDER BY-osa
   annetulla sarakkeen nimellä ja suunnalla "ASC" tai "DESC"
   riippuen parametrista orderingDir.
- Hae tietokantayhteys kutsulla getConnection(db)
- Suorita kysely
- Luo kyselyn tuloksesta DBResult-olio ja palauta se
    

public static String getPageLogic(String name)
- Hae logicxml-taulusta sarake address riviltä, jossa nimi täsmää annettuun
 käyttäen getFromDatabase-metodia.
- Jos täsmäävä rivi löytyi, hae address-merkkijonon osoittamasta URLista löytyvä XML 
metodilla getStringFromURL ja palautta se
    

public static String getLogicXSL(String name)
- Hae logicxsl-taulusta sarake address riviltä, jossa nimi täsmää annettuun
 käyttäen getFromDatabase-metodia.
- Jos täsmäävä rivi löytyi, hae address-merkkijonon osoittamasta
 URLista löytyvä XSL metodilla getStringFromURL ja palautta se
    

private static String getStringFromURL(String urlStr)
- Luo java.net.URL-instanssi annetulla merkkijonolla
- Avaa URL:in InputStream
- Luo InputStreamin sisältö ja palauta se merkkijonona
    

public static String login(String name, String password)
- Hae login-taulusta kaikki sarakkeet riviltä, jossa nimi
 ja salasana täsmäävät annettuihin käyttäen getFromDatabase-
 metodia.
- Mikäli tulos on tyhjä, tuota InvalidLoginException,
 muutoin palauta tulos XML:änä (käyttäen metodia DBResult.toXML())
    

public static String loadOffer(int offerId)
- Hae offer-taulusta sarake offer_xml annettuun ID:hen täsmäävältä
 riviltä käyttäen getFromDatabase-metodia.
- Jos rivi löydettiin, palauta sarakkeen offer_xml sisältö
    

public static void saveOffer(String offerXML)
- Selvitä annetusta XML:stä myyjän ja asiakkaan tunnukset
 metodilla getSellerAndCustomerIds
- Hae tietokantayhteys TaHKo-tietokantaan (getConnection)
- Aseta myyjän ja asiakkaan tunnukset, tämänhetkinen aika ja offerXML
 uudelle riville tietokantaan
    

public static void updateOffer(int id, String offerXML)
- Selvitä annetusta XML:stä myyjän ja asiakkaan tunnukset
 metodilla getSellerAndCustomerIds
- Päivitä parametrina annetun ID:n osoittamalle riville
 myyjän ja asiakkaan tunnukset, tämänhetkinen aika ja offerXML
    

private static String[] getSellerAndCustomerIds(String xml)
- Luo kaksi-alkioinen String taulukko ids.
- Muodosta XML:stä DOM dokumentti
- Hae dokumentista tagin 'seller_id' sisältö ja aseta se ids-taulukon
 ensimmäiseksi alkioksi.
- Hae dokumentista tagin 'customer_id' sisältö ja aseta se ids-taulukon
 toiseksi alkioksi.
- Palauta ids-taulukko
    

5.5.2.2. DBResult


Metodit:

public DBResult(ResultSet rs, String tableName) [konstruktori]
- Aseta instanssin muuttuja tableName
- Hae ResultSetMetaData ja aseta instanssin muuttuja columnCount
 metadatasta saatavan sarakkeiden määrän mukaan
- Lue sarakkeiden nimet columnNames-taulukkoon,
 luo jokaiselle sarakkeelle vektori (columns-taulukko)
 ja aseta se columnTable-hajautustauluun sarakkeen nimellä
- Käy läpi kaikki ResultSet:in rivit ja luo niiden sarakkeet
 columns-vektoreihin. Laske rivien määrä muuttujaan rowCount.
  

public int getRowCount()
- Palauta rowCount

public int getColumnCount()
- Palauta columnCount
  

public Object getObject(String columnName, int row)

public String getString(String columnName, int row)

public int    getInt(String columnName, int row)

public double getDouble(String columnName, int row)
- Etsi oikea sarake-vektori columnTable hajautustaulusta
 annetun sarakkeen nimen perusteella
- Mikäli sarake löytyi, ja parametri row on välillä [0 - rowCount),
 palauta sieltä löytyvä arvo haluttuna tietotyyppinä.
 Mikäli tietotyyppi on väärä, tuota InvalidValueTypeException. 
  

public Object getObject(int column, int row)

public String getString(int column, int row)

public int    getInt(int column, int row)

public double getDouble(int column, int row)
- Etsi sarakkevektorista column alkio row, mikäli
 parametrit column ja row ovat laillisissa rajoissa
- Palauta löydetty arvo haluttuna tietotyyppinä.
 Mikäli tietotyyppi on väärä, tuota InvalidValueTypeException.
  

public String toXML()
- Aloita XML:n tuottaminen <db-result>-tagilla, jossa parametrina 'table'
 taulun nimi.
  

- Jos rivejä on lisää <records>-tagi ja käy läpi kaikki rivit r:
   *lisää XML:ään <record>-tagi
   *Käy läpi kaikki sarakkeet s:
     +Lisää XML:ään <column>-tagi, jossa parametrina 'name'-sarakkeen nimi
     +lisää XML:ään sarakkeelta s ja riviltä r löytyvä arvo nerkkijonona tai
     +tyhjä merkkijono mikäli se on null.
     +Lisää XML:ään </column> tagi.
   *Lisää XML:ään </record>-tagi.
 Lisää </records>-tagi.
 Jos rivejä ei ole, lisää <no_records_found/>-tagi
- Lisää lopuksi XML:ään </db-result>-tagi
- Palauta XML
  

public CoreDocumentImpl toDOM()
- Muuten kuten toXML, mutta Stringin sijasta muodostetaan DOM-puu.
      

Luku 6. Servlet

6.1. Yleiskuvaus

Tämä osajärjestelmä huolehtii yhteydenpidosta TAHKO:n käyttäjien www-selaimiin. Osajärjestelmä sisältää vain yhden luokan: TahkoServlet, joka on HttpServletin aliluokka. Osajärjestelmä on nimensä mukaisesti servletti; se ladataan Tomcatiin, ja Tomcat kutsuu sen metodeja käyttäjän selaimestaan lähettämien http-requestien perusteella.

Servlet-osajärjestelmän metodeja käyttää ainostaan Tomcat. Sen sijaan Servlet itse kutsuu Db- ja ApacheWrapper -osajärjestelmien metodeja.

6.2. TahkoServlet

Tämä on servlet-osajärjestelmän ainoa luokka. Se on periytetty javax.servlet.HttpServlet:stä.

6.2.1. Liittymäsuunnitelma

public void init(ServletConfig config) throws ServletException

Tämä on kuormitettu versio HttpServetin vastaavannimisestä funktiosta, joka käsittelee servletille annettavat, komentoriviparametrejä vastaavat alustusparametrit.

parametri: config servletille annettavat alustusparametrit. Tomcatia käytettäessä nämä annetaan web.xml -tiedostossa.

protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException

Tämä on kuormitettu versio HttpServetin vastaavannimisestä funktiosta, joka käsittelee käyttäjän www-selaimelta tulevan http get -pyynnön.


parametri: req käyttäjän selaimelta tuleva http-request
parametri: res käyttäjän selaimelle palautettava http-vastaus
      

protected void doPost(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException
      

Tämä on kuormitettu versio HttpServetin vastaavannimisestä funktiosta, joka käsittelee käyttäjän www-selaimelta tulevan http post -pyynnön.


parametri: req käyttäjän selaimelta tuleva http-request
parametri: res käyttäjän selaimelle palautettava http-vastaus
      

6.2.2. Toimintosuunnitelma


public void init(ServletConfig config) throws ServletException {
 
//KUTSUTAAN YLILUOKAN INIT() 
super.init(config);     

//ALUSTETAAN APACHEWRAPPER
jspProcessor = new TomcatWrapper(this,
               config,properties.getProperty(JSP_DIR),
               config.getServletContext()); 
 
//ALUSTETAAN DBSLAVE
DbSlave.setDBServer(properties.getProperty(DB_PROPERTIES));

//ALUSTETAAN SERVLETIN ITSENSÄ MUUTTUJIA 
profileDTD = new URL(properties.getProperty(DTD_PROFILE));  

}
    

protected void doGet(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {

//JOS HALUTTUA JSP-SIVUA EI OLE KÄÄNNETTY
if (!TomcatWrapper.isTranslated(pageId)) { 
    
 
        //TEHDÄÄN JSP-XML:ää
        String jspXML = XMLProcessor.transform(db.getLogicXML(pageId), 
                        db.getLogicXSL());
        //TEHDÄÄN OIKEAA JSP:tä
        String jsp = XMLProcessor.transform(logicXML, db.getJSPXSL());  

        //KÄÄNNETÄÄN JSP
        TomcatWrapper.translate(pageId,jsp);

}
    

//AJETAAN JSP
String xmlDataPage = TomcatWrapper.service(pageId, req, res); 

//PÄIVITETÄÄN PROFIILI DATA_XML:n MUKAISEKSI
Profile.update(xmlDataPage);   

//LUODAAN KÄYTTÖLIITTYMÄ
String uiPage = XMLProcessor.transform(xmlDataPage, db.getUIXSL()); 

//PALAUTETAAN KÄYTTÖLIITTYMÄ
res.write(uiPage);    
 
}
    

protected void doPost(HttpServletRequest req, HttpServletResponse res)
    throws ServletException, IOException {
    //DELEGOIDAAN DOGET():LLE
    this.doGet(req, res);     
}
    

Luku 7. ApacheWrapper

7.1. ApacheWrapper

ApacheWrapper on osajärjestelmä, jonka tehtävänä on kapseloida Apachen (www.apache.org) työkalut. Tässä dokumentoidut luokat ja metodit ovat kaikki julkisia, ja muodostavat siten rajapinnan muihin osajärjestelmiin (kuva 7.1).

Kuva 7.1: ApacheWrapperin luokat

7.2. FopWrapper

Tämä työkaluluokka kapseloi Apachen Fop PDF-generaattorin.

7.2.1. Liittymäsuunnitelma

 
public static String transform(String xml, String fopXSL)
    throws PDFProcessingException
 
   Staattinen Funktio, joka tuottaa lopullisen tarjouksen PDF-fomaatissa.
   parametri: savedXML tarjous-XML talletusmuodossaan
   parametri: fopXsl XSL-tiedosto, joka konvertoi tarjous-XML:n Fop:n ymmärtämään muotoon 
   paluuarvo: tarjous PDF-formaatissa
   poikkeus: PDFProcessingException, aiheutetaan jos PDF:n luonti ei onnistu
    

7.2.2. Toimintosuunnitelma


public static String transform(String xml, String fopXSL)
    throws PDFProcessingException { 

//KUTSUTAAN OMAA XMLPROCESSOR:IA
String pdfXML = XMLProcessor.transform(xml, fopXSL);

//KUTSUTAAN APACHEN FOP:IA
return Fop.process (pdfXML);
 
}
    

7.3. XmlProcessor

Tämä työkaluluokka kapseloi Apachen Xalan XML-prosessoijan.

7.3.1. Liittymäsuunnitelma


public static String transform(String xml, String xsl)
    throws XMLProcessingException 


Staattinen funktio, joka suorittaa xsl-muunnoksen annetulle xml-merkkijonolle 
parametri: xml xml-muotoinen merkkijono, joka halutaan käsitellä  
parametri: xsl xsl, jolla annettu xml käsitellään  
paluuarvo: xsl-muunnoksen tuloksena syntynyt merkkijono
poikkeus: XmlProcessingException, aiheutetaan jos xsl-muunnos ei onnistu 
    

7.3.2. Toimintosuunnitelma


public static String transform(String xml, String xsl)
    throws XMLProcessingException { 

return Xalan.process(xml,xsl); //KUTSUTAAN APACHEN XALANIA

}
    

7.4. TomcatWrapper

Tämä työkaluluokka kapseloi Apachen Tomcat jsp-koneen.

7.4.1. Tietosuunnitelma


Map pages

Map, jossa pidetään jo Servlet-muotoon käännetyt JSP-sivut,
jotta niitä ei tarvitse kääntää uudelleen. 
    

7.4.2. Liittymäsuunnitelma


 public TomcatWrapper(Servlet servlet, ServletConfig config, File jspTempDir,
       ServletContext ctxt)
    throws ServletException 

Konstruktori. 
parametri: servlet Servlet, josta TomcatWrapperia käytetään 
parametri: config  Sen servletin config, josta TomcatWrapperia käytetään  
parametri: jspTempDir hakemisto tilapäisille tiedostoille
parametri: ctxt Sen servletin context, josta TomcatWrapperia käytetään  


public boolean isTranslated(String pageId) 

Funktio, joka kertoo onko sivu käännetty vai ei.
parametri: pageId kyseltävän sivun id 
paluuarvo: true, jos sivu on jo käännetty, muuten false
    

public void translate(String pageId, URL pageSource)
    throws IOException, ParseException 

Funktio, joka kääntää JSP-sivun Tomcatin avulla ajettavaan muotoon.

parametri: pageId käännettävän JSP-sivun id
parametri: pageSource URL, josta käännettävä JSP-sivu haetaan 

public String service(String pageId, HttpServletRequest req,
HttpServletResponse res)
     throws IOException, PageNotFoundException, ServletException 

Funktio, joka suorittaa annetun http-requestin halutulle, valmiiksi servletiksi 
käännetylle JSP-sivulle.  

parametri: pageId halutun JSP-sivun id 
parametri: req JSP-sivulle välitettävä request
parametri: res JSP-sivun palauttama response
paluuarvo: JSP-sivun palauttama XML-merkkijono
poikkeus: PageNotFoundException aiheutetaan, jos sivua ei löydy
    

7.4.3. Toimintosuunnitelma


public boolean isTranslated(String pageId) { 

return return pages.containsKey(pageId);

}

public void translate(String pageId, URL pageSource)
    throws IOException, ParseException {

pages.put (pageId, tomcat.translate (getPageWithId()));



public String service(String pageId, HttpServletRequest req,
HttpServletResponse res) 
   throws IOException, PageNotFoundException, ServletException {

pages.get(pageId).service(req,res);
return res.toString();  //oikeasti vaikempi toteuttaa, toString() on vain kuvaava nimitys 

}
    

Luku 8. Profiili

8.1. Yleiskuvaus

Tämä osajärjestelmä huolehtii sessionhalinnasta käyttäjän tehdessä tarjousta TAHKO:lla. Profiili-osajärjestelmä tallettaa käyttäjän tekemät asiakas- ja tuotevalinnat xml-muodossa käyttösession ajaksi. Lopussa profiili-osajärjestelmään kootusta XML:stä tehdään lopullinen PDF-tarjous. Profiili-osajärjestelmää käytetään JSP-sivuilta käsin sekä Servletistä.

8.2. Profile (interface)

Profile on rajapintaluokka, joka määrittelee sessionhallinnassa käytettävän profiilin rajapinnan.

8.2.1. Liittymäsuunnitelma


public void addElement(String name, String id);

Lisää elementin profiiliin
parametri: name lisättävän elementin nimi
parametri: id lisättävän elementin id
      

public void importDatabaseData(String name, String id, DBResult data,
                                 boolean clear);

Lisää profiiliin elementin jos, sitä ei vielä ole olemassa. 
Lisää elementtiin kentät, jotka saavat nimensä ja arvonsa tietokantahaun tuloksesta.

parametri: name halutun elementin nimi 
parametri: id halutun elementin id
parametri: data tietokantahaun tulos, joka asetetaan halutun elementin kentiksi 
parametri: clear jos clear on tosi, haluttu elementti päällekirjoitetaan  
      

public void removeElement(String name, String id);

Poistaa elementin profiilista.

parametri: name halutun elementin nimi 
parametri: id halutun elementin id
      

public void removeField(String name, String id, String field);

Poistaa nimetyn kentän halutusta elementistä.

parametri: name halutun elementin nimi 
parametri: id halutun elementin id
parametri: field poistettavan kentän nimi
      

public void setField(String name, String id, String field, String value);

Asettaa nimetylle kentälle uuden arvon halutussa elementissä.

parametri: name halutun elementin nimi 
parametri: id halutun elementin id
parametri: field asetettavan kentän nimi
parametri: value kentälle asetettava uusi arvo 
      

public ItemElement[] getElements(String name);

Palauttaa Profiilista halutunnimiset elementit filtteröintiin (siis esim. xml-muunnokseen)
soveltuvina itemeinä.

parametri: name haluttujen elementtien nimi
paluuarvo: elementit itemeinä  
      

public void resetProfile();

Tyhjentää profiilin.
      

8.3. ItemElement (interface)

Tämä rajapintaluokka on periytetty Item-rajapinnasta. Se sisältää kaksi uutta metodia, jotka sopivat profiilielementtien käsittelyyn.

8.3.1. Liittymäsuunnitelma


public String getName();

Paluttaa elementin nimen.
paluuarvo: elementin nimi
 
public Map getFields();

Palauttaa elementin kenttien nimet ja kenttien arvot. 
paluuarvo: elementin kenttien nimet ja kenttien arvot.
      

8.4. MyItemElement

Tämä luokka toteuttaa ItemElement-rajapinnan. Se tallettaa elementin kentät Javan TreeMap -olioon.

8.4.1. Tietosuunnitelma


private final String name;

Tämä on elementin nimi.

private final String id;

Tämä on elementin id.

private int state;

Tämä on elementin tila, kuten määritelty item-rajapinnassa. 

private final Map fields;

Tämä on TreeMap, johon elementin kentät tallennetaan. 
      

8.4.2. Liittymäsuunnitelma (Item- ja ItemElement-rajapintoihin kuulumattomat metodit)


public MyItemElement(Node node, int state)

Konstruktori.
parametri: node elementti DOM-puusta 
parametri: state elementin tila, eli onko se valittavissa vai ei 
      

8.4.3. Toimintosuunnitelma (vain konstruktori, muut metodit triviaaleja)


public MyItemElement(Node node, int state) {
  this.state = state;
  this.name = node.getAttributes().getNamedItem("name").getNodeValue();
  this.id = node.getAttributes().getNamedItem("id").getNodeValue();

  NodeList list = node.getChildNodes();

  for (int i = 0; i < list.getLength(); ++i) {
    Node n = list.item(i);
    fields.put(n.getAttributes().getNamedItem("name"), n.getNodeValue());
  }

}
      

Luku 9. Muuta

Joissain kohdissa suunnittelua hidasteena tai haittana tarkalle suunnittelulle ilmeni kokemuksen puute vastaavista järjestelmistä ja niiden suunnittelusta. Kaiken kaikkiaan suunnittelu eteni kuitenkin hyvin, sillä porukasta löytyi ainakin yksi, joka hallitsi asian ja siten toteutus pysynee melko suoraviivaisena ja dokumentin pitäisi olla kattava.