1. Johdanto
2. Arkkitehtuurin yleiskuvaus
3. Dokumentit
4 Tiedostot
5. Rajapinnat
6. Toimintaympäristö
6. Jatkokehittäminen
6.1 JDK 1.3
6.2 Servlet API
6.3 PostgreSQL-tietokanta
6.4 XML-kirjasto
6.5 Log4J
7. Ohjelmiston asennus
7.1 Asiakasohjelmisto
7.2 Palvelin
8. Jatkokehittäminen
8.1 Esitietovaatimukset
8.2 Suunnitteluperiaatteet
8.3 Kääntäminen
8.4 Moduulien lisääminen ja vaihto ohjelmistoon
8.5 Virheiden etsintä
8.6 Konfigurointi
8.7 Jatkokehittämisohjeita
9. Tiedossa olevia virheitä ja vajeita
10. Viitteet
Versio |
Pvm |
Muutos |
Muuttaja |
0.1 |
18.1.2001 |
T3-vaiheen ensimmäinen versio |
Niko |
1.0 |
8.2.2001 |
T3-vaiheen toinen versio |
Niko |
1.1 |
15.3.2001 |
T4-vaiheen palautettava versio |
Niko |
1.5 |
9.4.2001 |
LU-vaiheen ensimmäinen versio, asiakkaalle ja eTLA:lle |
Juha, Kari, Santeri ja Teemu |
1.9 |
21.4.2001 |
LU-vaiheen toinen versio |
Juha |
Dokumentti on Teknillisen korkeakoulun ohjelmistotyökurssilla tehtävän Osprey-projektin käyttöohjeen liite. Se on tarkoitettu arkkitehtuurin jatkokehittämisen avuksi. Osprey-projektin käyttöohje keskittyi pelkästään asiakasohjelmiston kuvaamiseen. Siksi katsottiin järkeväksi tehdä erillinen käyttöohje arkkitehtuurille. Tämä oli myös asiakkaan toivomus.
Kehittämisohjeen tarkoitus on toimia oppaana Osprey-projektin arkkitehtuuria koskevaan materiaaliin, koota näistä dokumenteista järkevä yleiskuvaus sekä antaa viitekehys jatkokehittämiseen. Dokumentti sisältää kuvauksen Osprey-projektiin kuuluvista tiedostoista, käyttöympäristön vaatimukset sekä esimerkinomaisia jatkokehitysohjeita. Lisäksi dokumentti sisältää arkkitehtuurin asennusohjeet.
Tämä dokumentti on tarkoitettu projektin asiakasta varten. Tavalliselle asiakasohjelmiston kayttäjälle on erikseen oma käyttöohje [OSPREY-K].
Arkkitehtuurin tekninen yleiskuva löytyy teknisestä määrittelystä [OSPREY-T].
Osprey-projektin aikana on tehty useita dokumentteja, jotka liittyvät projektin tuotteena olevaan kalenteriin. Näihin dokumentteihin on hyvä perehtyä ennen jatkokehittämistä.
Käyttöohje
Tekninen määrittely
Tekninen määrittely, asiakasohjelmistoliite
Testaussuunnitelma
Termit
Toiminnallinen määrittely
Toiminnallinen määrittely, käyttöliittymä
Vaatimusmäärittely
Kaikki em. dokumentit löytyvät CD:ltä.
Alla oleva hakemistolistaus käsittää ohjelmiston CD:n hakemistorakenteen.
README | Lue minut ensiksi! |
LICENSE | GNU GPL lisenssi |
src/ | Lähdekoodit |
doc/ | Dokumentaatio |
doc/javadoc | Lähdekoodin Java-dokumentaatio |
doc/kayttoohje | Käyttöohjeet (tämä dokumentti ja asiakasohjelmiston) |
doc/kehitysdokumentit | Sekalaisia kehitysdokumenttejä |
doc/muut | Sekalaisia muistiinpanoja |
doc/projektisuunnitelma | Projektisuunnitelma |
doc/skenaariot/ | Projektin lähtökohtana toimineet skenaariot |
doc/tekninenmaarittely | Projektin tekninen määrittely |
doc/testaus | Testaukseen liittyvä dokumentaatio |
doc/toiminnallinenmaarittely | Projektin toiminnallinen määrittely |
doc/vaatimusmaarittely | Projektin vaatimusmäärittely |
bin/ | Valmis asiakasohjelmisto ja palvelin |
conf/ | Esimerkkikonfiguraatiotiedostot |
lib/ | Vaaditut kirjastot (JDBC, Xerces, Servlet, Log4J) |
clientpics/ | Asiakasohjelmiston vaatimat kuvat |
Alla oleva listaus kuvaa lähdekoodin rakenteen ja samalla Java-pakettien hierarkian ja sisällön.
JLex/ | JLex-lähdekoodit |
java_cup/ | JavaCUP-lähdekoodit |
FI/hut/cs/osprey/ | Osprey-projektin lähdekoodit |
FI/hut/cs/osprey/client | Asiakasohjelmisto |
FI/hut/cs/osprey/common | Palvelimen ja asiakasohjelmiston mahdollisesti yhteisiä osia |
FI/hut/cs/osprey/common/cap | CAP-asiakasohjelmisto |
FI/hut/cs/osprey/common/core | Ydin |
FI/hut/cs/osprey/common/config | Konfiguraatiotuki |
FI/hut/cs/osprey/common/directory | Hakemistopalvelu |
FI/hut/cs/osprey/common/distiller | Jalostajat |
FI/hut/cs/osprey/common/filter | Suodattimet |
FI/hut/cs/osprey/common/icalendar | iCalendar-esitysmuoto |
FI/hut/cs/osprey/common/importer | XML-sisääntuoja |
FI/hut/cs/osprey/common/module | Ytimen moduulituki |
FI/hut/cs/osprey/common/location | Etäisyyslaskuri |
FI/hut/cs/osprey/common/repository | Tietovarastot |
FI/hut/cs/osprey/common/watcher | Käyttäjän sijainnin tarkkailu |
FI/hut/cs/osprey/common/watcher/sms | SMS-hälytykset |
FI/hut/cs/osprey/server | Palvelin |
FI/hut/cs/osprey/server/parser | Palvelimen tuetut protokollat (CAP) |
Rajapintojen kuvaukset löytyvät teknisen määrittelyn ([OSPREY-T]) luvusta neljä.
Osprey kalenteria kehitettäessä on palvelimessa käytetty Sunin Java Developer's Kit 1.3 -ympäristöä Debian GNU/Linux-ympäristössä. Osprey-palvelin toimii myös muissa käyttöjärjestelmissä, joille on saatavilla JDK 1.3. Osoitteesta http://java.sun.com/ on ilmaiseksi imuroitavissa versiot Windows-, Linux- ja Solaris-käyttöjärjestelmille. Todennäköisesti palvelin toimii myös JDK 1.2.x versiolla, koska mitään merkittäviä rajapintamuutoksia ei tiettävästi ole, mutta tätä ei ole testattu. JDK 1.1 ei toimi, koska Ospreyssä on käytetty Java 2:n (JDK 1.2) myötä tullutta Collections APIa, sekä JDBC 2.0 rajapintaa.
Asiakasohjelmisto on toteutettu Java2-servlettinä ja sen kääntämiseen vaaditaan Sun Microsystemsin Java Servlet API
Asiakasohjelmisto on toteutettu Java2-servlettinä ja sen ajamiseen vaaditaan Apachen Jakarta-Tomcat implementaatio
Kun PostgreSQL on asennettu, on hyvä tapa luoda Osprey-palvelimelle oma looginen
tietokantansa, vaikka periaatteessa voitaisiin käyttää myös PostgreSQL
vakiokantaa template1 tms. Kannan luominen tapahtuu komentorivityökalulla
"createdb osprey".
Kyseisellä Unix-käyttäjällä täytyy olla oikeus luoda tietokantoja.
Helpointa on käyttää Unix-käyttäjätunnusta postgres, joka on
PostgreSQL-tietokannan oletusylläpitäjä. Mikäli halutaan käyttää muuta
käyttäjätunnusta, siihen löytyy ohjeet PostgreSQL-manuaalista.
Täysin Unix-käyttäjätunnuksista
erillinen asia on PostgreSQL-käyttäjä, joka luodaan komennolla
"createuser -P ospreyuser".
Kun kanta on luotu, tarvitsee se kantamäärityksen. Tarvittava schema löytyy
CD:ltä tiedostosta src/FI/hut/cs/osprey/common/icalendar/schema.sql
. Se ajetaan
kantaan osprey komennolla "psql -U ospreyuser -f schema.sql osprey".
Tiedostosta src/FI/hut/cs/osprey/common/icalendar/testdata.sql
löytyy
esimerkkikäyttäjien lisäys kantaan.
Tietokanta on syytä suojata luvattomalta käytöltä rajoittamalla osoitteita, joista tietokantaan saa ottaa yhteyden. Tämä tapahtuu editoimalla PostgreSQL PGDATA -hakemistosta tiedostoa pg_hba.conf. Rivi "host all 1.2.3.4 255.255.255.255 password" sallii yhteydet osoitteesta 1.2.3.4 vaatien selväkielisen salasanan. Tarkemmat tiedot kannan turvaamisesta löytyvät PostgreSQL-manuaalista kappaleesta "28. Security".
PostgreSQL ei myöskään ole ainoa mahdollinen tietokanta,
kunhan kantaan löytyy JDBC 2.0-yhteensopivat ajurit Javalle. Muita kantoja
ei kuitenkaan ole testattu, joten niiden käyttäminen aiheuttaa
ylimääräistä työtä. PostgreSQL tuotantoajuritkaan eivät toteuta, tai ainakaan
kokeiluhetkellä toteuttaneet JDBC 2.0 -rajapintaa, joten osprey-käyttöä
varten niitä täytyy patchata. Korjatut PostgreSQL-JDBC-ajurit (version 7.0.2 pohjalta)
löytyvät ohjelmiston CD:ltä hakemistosta lib
. PostgreSQL JDBC-ajurien kotisivu löytyy
osoitteesta http://jdbc.postgresql.org/.
PostgreSQL:n JDBC-ajurit ovat tyyppiä 4, eli ne ovat puhdasta Javaa.
Tietokantayhteyden parametrit määritellään ospreyn asetustiedostossa
conf/osprey.conf
. Siellä tarvitaan seuraavat asetukset:
Kumpikaan, kalenteripalvelin eikä asiakasohjelmisto, ei käytä XML:ää mihinkään.
Kalenterimerkintöjä voi kuitenkin tuoda kalenteripalvelimeen XML-tiedostosta. Mikäli
käytetään tätä erillistä työkalua, tarvitaan
Apachen Xerces XML-kirjasto xerces.jar
Javan
CLASSPATH
:iin. Ks. kappale 8.7.13.
Kalenteripalvelin sekä asiakasohjelmistona toimiva servlet käyttävät Apache-
projektin Log4J monipuolista
lokimoduulia. Java CLASSPATH
:iin pitää siis sisältää Log4J:n kirjasto
log4j.jar
.
Asiakasohjelmiston tarvitsemat Java-luokat pitää kopioida paikkaan, josta Jakarta-Tomcat ne
löytää, esim. hakemistoon /usr/local/jakarta-tomcat/lib/
, josta Tomcat
löytää luokat automaattisesti. (Tässä oletetaan, että Jakarta-Tomcat on asennettu
hakemistoon /usr/local/jakarta-tomcat/
).
Asiakasohjelmisto vaatii seuraavat paketit toimiakseen:
osprey-client.jar
: asiakasohjelmiston käännetyt luokat
log4j.jar
: Log4J-lokimoduuli
servlet.jar
: Sun Microsystemsin servlet-kirjasto
/usr/local/jakarta-tomcat/lib/
.
Tiedostojen kopioinnin jälkeen Tomcat on käynnistettävä uudelleen, jotta se havaitsee uudet paketit.
Luokkatiedostojen lisäksi asiakasohjelmisto tarvitsee grafiikan tuottamiseen kuvat, jotka
löytyvät CD:lta hakemistosta clientpics
. Kuvat tulee kopioida Tomcatin
webapps/test/
hakemistoon, mista servlet niita yrittaa hakea.
Ks. kappale 8.6.1 miten asiakasohjelmisto konfiguroidaan.
Konfiguraatiotiedoston muokkauksen jälkeen asiakasohjelmisto voidaan käynnistää avaamalla WWW-selaimella
sivu: http://<Apache-palvelin>:8080/servlet/FI.hut.cs.osprey.client.Client
. (Tässä
oletetaan, että Jakarta-Tomcat vastaanottaa kutsuja portista 8080.)
Asennus koostuu seuraavista vaiheista:
bin
ja esimerkkikonfiguraatiotiedostot
hakemistosta conf
. Palvelinohjelmisto löytyy tiedostosta osprey.jar
.
CLASSPATH
:n osalta.
Sen tulee pitää sisällään niin tarvittavat lisäkirjastot kuin itse kalenteripalvelimen
ajonaikaistiedosto, osprey.jar
. Alla esimerkki CLASSPATH
tilanteesta
jossa lisäkirjastot on sijoitettu /usr/share/java
:aa ja itse palvelin
hakemistoon /usr/local/osprey
.
/usr/local/osprey/osprey.jar:/usr/share/java/log4j.jar:/usr/share/java/jdbc7.0-1.2.jar:\ /usr/share/java/xerces.jar
FI.hut.cs.osprey.common.icalendar
. Ks. kappale 8.7.11 miten käyttäjätiedot
lisätään kantaan ja kappale 6.3 miten schema asennetaan PostgreSQL-tietokantaan.
java FI.hut.cs.osprey.server.CalendarServerParametreiksi voidaan antaa konfiguraatiotiedoston sijainti optiolla
-f <tiedoston_sijainti>
ja Log4J:n konfiguraation sijainti optiolla -l <tiedoston_sijainti>
. Konfiguraatiotiedostoa
haetaan oletusarvoisesti sijainnista /etc/osprey.conf
ja mikäli lokikonfiguraatiota ei
löydy parametreistä, käytetään Log4J:n peruskonfiguraatiota, joka tulostaa lokiviestit konsolille.
Kehittäjältä oletetaan tuntemusta ainakin seuraavista asioista:
Käytettyjen työkalujen tarkemmat kuvaukset löytyvät luvusta kuusi.
Suunnitteluperiaatteiden tarkka kuvaus löytyy teknisen määrittelyn ([OSPREY-T]) luvusta 3.1. Tärkein suunnitteluperuste oli modularisointi hyvin määriteltyjen rajapintojen avulla.
Sekä asiakasohjelmiston että palvelimen kääntäminen lähdekoodeista tapahtuu
käyttämällä Apache-projektin Ant make-työkalua.
Tarvittava XML-pohjainen make-tiedosto löytyy CD:n juurihakemistosta nimellä
build.xml
.
Kääntäminen vaatii kappaleessa 6 mainitut kirjastot Javan CLASSPATHiin
.
Projektin makefile tunnistaa seuraavat käännöskokonaisuudet:
clean
- siivoaa edellisten käännösten jäljiltä class
-tiedostot pois.
dist-server
- rakentaa palvelimen jar
-tiedoston.
dist-client
- rakentaa asiakasohjelmiston jar
-tiedoston.
compile-parser
- kääntää kieliopista ja selainsäännöistä uuden kääntäjän. Olettaa
JavaCUP:n ja JLex:n löytyvän CLASSPATH
:sta.
release
- rakentaa Osprey-projektin lopullisen distribuution tar-palloon.
On huomattava, että Ant ei build.xml
-tiedoston määrityksien perusteella
tunne käännettävien luokkien riippuvaisuuksia. Suuria muutoksia tehdessä kannattaa
siis vanhat käännökset siivota pois ennen uutta käännöstä.
Eri moduulien korvaaminen toisilla saman rajapinnan toteuttavilla moduuleilla
on helppoa: muutat vain kalenteriserveriluokasta FI.hut.cs.osprey.server.CalendarServer
ladattavat moduulit.
Muihin tiedostoihin ei tarvitse koskea, pelkkä kalenteriserveriluokan
uudelleenkääntäminen riittää. Ladattavat moduulit olisi lisäksi melko
helppo muuttaa haettavaksi konfiguraatiotiedostosta, jollain mitään
ei tarvisi uudelleenkääntää moduulien vaihtuessa.
Sekä palvelimen että asiakasohjelmiston vikojen etsintä kannattaa suorittaa hyväksikäyttäen Log4J:n monipuolisia mahdollisuuksia rajata lokimerkintöjä. Projektin tuotoksissa on käytetty luokkakohtaista erottelua lokiviesteille ts. lokiviestit on mahdollista suodattaa hyvinkin tarkasti käyttäen Log4J:n lokimäärityksiä.
Oletetaan esimerkiksi, että kehittäjä haluaa tutkia miksi suodattimet tekevät outouksiaan. Mahdollisuuksia on kaksi:
FI.hut.cs.osprey.common.distiller
lokimerkinnät.
grep
:aamalla yksittäiseen käyttäjään liittyvät
lokimerkinnät.
Lisätietoja Log4J:n tarjoamista mahdollisuuksista muokata, suodattaa ja uudelleenohjata lokimerkintöjä löytyy ohjelmiston kotisivulta runsaasti.
Asiakasohjelmisto lukee käynnistyessään konfiguraatiotiedoston /etc/osprey-client.conf
(esimerkkitiedosto osprey/src/conf/osprey.conf
). Tässä tiedostossa määritellään
asiakasohjelmiston käyttäjien kalenteripalvelimen IP-osoite ja portti, jota kalenteripalvelin kuuntelee, sekä hakemistopalvelimen IP-osoite ja portti.
Esimerkkitiedoston sisältö:
########################################################################### # IP-address of the calendar server # SERVER_ADDRESS=ohjtyo-13.cs.hut.fi ########################################################################## # Port of the calendar server # SERVER_PORT=8889 ########################################################################### # IP-address of the directory server # DIRECTORY_ADDRESS=ohjtyo-13.cs.hut.fi ########################################################################## # Port of the directory server # DIRECTORY_PORT=9999
Servlet käsittelee em. konfiguraatiotiedostoa standardina ns. Java property -tiedostona.
Alla on esimerkki palvelimen konfiguraatiotiedostosta. Konfiguraatiotiedostoa
haetaan oletusarvoisesti sijainnista /etc/osprey.conf
.
########################################################################### # Osprey JDBC local database storage connection URL # DATABASE_URL=jdbc:postgresql://localhost:5432/osprey ########################################################################### # Osprey JDBC database user name # DATABASE_USERNAME=osprey ########################################################################### # Osprey JDBC database user password # DATABASE_PASSWORD=osprey ########################################################################### # Osprey CAP listener port number # CAP_LISTENER=8889 ########################################################################### # Osprey Simple Directory Service listener port number # DIRECTORY_LISTENER=9999 ########################################################################### # Watcher on/off. Watcher triggers alarms (sends SMS message). # WATCHER=YES ########################################################################### # Watcher on/off. Predict generates alarms, if user is not near # the location next event / todo is happening at. # PREDICT=YES
Alla on kuvattuna yo. konfiguraatio-optiot tarkemmin.
CAP_LISTENER
määrittää TCP-portin, jota palvelin kuuntelee
sisääntuleville CAP-yhteyksille.
DIRECTORY_LISTENER
määrittää TCP-portin, jota palvelin kuuntelee
sisääntuleville käyttäjän sijaintipäivityksille.
WATCHER
määrittää onko hälytyksien lähetys päällä vai ei.
Mikäli käytetään maksullista SMS-palvelua hälytyksien lähetykseen, saattaa olla
hyödyllistä saada kehityksen aikana em. ominaisuus pois päältä. Mahdolliset
arvot ovat YES
ja NO
.
PREDICT
määrittää onko hälytyksien automaattinen luonti
käyttäjän sijainnin perusteella päällä vai ei. Mahdolliset
arvot ovat YES
ja NO
.
Konfiguraatiotiedoston luku on toteutettu Java-paketissa
FI.hut.cs.osprey.common.config
. Konfiguraatio-optioita
ei ole paketissa määritelty, vaan staattiselta konfiguraatioluokalta
voidaan pyytää millä tahansa parametrin nimellä option arvoa. Mikäli
arvoa ei ole määritelty luetussa tiedostossa, heitetään poikkeus.
Alla on listattu konfiguraatio-optioiden lukuun tarkoitetut
metodit.
/** * Returns a value of the configuration item. * @param key The configuration item key searched. * @throws IllegalArgumentException if no item searched is found. * @return A value string defined by the item key. */ static String getString(String key) throws IllegalArgumentException; /** * Returns a value of the configuration item. * @param key The configuration item key searched. * @throws IllegalArgumentException if no item searched is found. * @return A value int defined by the item key. */ static int getInt(String key) throws IllegalArgumentException;
Lisätietoja miten Log4J konfiguroidaan löytyy ohjelmiston kotisivuilta.
Seuraavaan on koottu keskeisiä ohjeita arkkitehtuurin jatkokehityksen kannalta. Ohjeet on kirjoitettu tyylillä, joka vaatii käytännössä lähdekoodin lukua samalla kun ohjeita luetaan. Ohjeita lukiessa pitää siis varautua käyttämään runsaasti aikaa.
Jalostajien tekninen kuvaus ja toteutetut jalostajat löytyvät teknisen määrittelyn ([OSPREY-T]) luvusta 4.10.
Jalostajat muokkaavat kalenterikomentoja (lisäys, poisto, muokkaus, luku) ja
tuottavat siten lisäarvoa peruskalenteritoimintoihin. Jalostajien
tarkoituksena on mahdollistaa monipuolisten
älyominaisuuksien luominen itse kalenterirunkoon koskematta. Projektin
puitteissa on toteutettu muutama jalostajamoduuli
(pakkauksessa FI.hut.cs.osprey.common.distiller
), joista voi ottaa
mallia.
Jalostajamoduuleilla ei ole varsinaisesti mitään rajoituksia niiden monimutkaisuudelle: ne voivat tehdä mitä tahansa Java sallii. Kannattaa kuitenkin huomioida, että jalostajamoduuleita kutsutaan useasti, joten monimutkaiset käsittelyt voivat kuormittaa serveriä. Jokainen kalenterikomento suoritetaan omassa säikeessään, joten kuormitus tarkoittaa vain serverin hidastumista.
Alla on esimerkki yksinkertaisesta jalostajasta. Se tutkii tapahtuman otsikkotietoa ja määrittelee sen kategoriaan kiireinen (urgent), jos otsikossa esiintyy sana urgent.
01: public class TestDistillerModule implements DistillerModule, ModuleFactory { 02: private Core core; 03: 04: public static org.apache.log4j.Category cat = 05: org.apache.log4j.Category.getInstance(LunchCheckerModule.class.getName()); 06: 07: public void setCore(Core core) { 08: this.core = core; 09: try { 10: ((CalendarModule)core.getModule("calendar")).register(VCommand.MODIFY, this); 12: } catch(NotRegisteredException e) { 13: cat.warn("Couldn't register TestDistillerModule to calendar"); 14: } 15: } 16: public void distill(VProfile p, VCommand c) throws VCalendarError { 17: for(int j=0; j< c.numElements(); ++j) { 18: VEventTodoParent e = (VEventTodoParent)c.getElement(j); 19: if(e == null) 20: continue; 21: 22: StringTokenizer st = new StringTokenizer(e.getSummary()); 23: while(st.hasMoreTokens()) { 24: String s = st.nextToken(); 25: if("urgent".equals(s.toLowerCase())) 26: e.addCategory("urgent", "1"); 27: } 28: } 29: return; 30: } 31: public Module getInstance() { return this; } 32: }
Rivillä 1 kerrotaan, moduuli on jalostajamoduuli ja sen lisäksi osaa itse toimia moduulitehtaana. Rivillä 10 rekisteröidytään kalenterimoduuliin ja kerrotaan että käsittelemme MODIFY-tyyppisiä käskyjä. Rivillä 16 on varsinainen jalostusmetodi. Kalenterioperaatiomoduuli kutsuu tätä kun sopivan tyyppinen komento tulee sisään.
Rivillä 17 aloitetaan käskyn kaikkien tapahtumien läpikäynti. Rivillä 19 tarkistetaan onko tapahtuma käsiteltävää tyyppiä, tällä hetkellä kaikki tapahtumat ovat. Rivillä 22 hajoitetaan tapahtuman otsikko sanoiksi ja rivillä 25 tarkistetaan näitä sanoja. Jos sana kuuluu etsittyihin sanoihin tehdään merkintä kategorioihin rivillä 26. Kategorioihin merkittyjä tietoja voidaan myöhemmin käyttää hyväksi muissa moduuleissa.
Suodattimia käytetään valitsemaan joukosta kalenteriolioita
(VEvent
, VTodo
jne.) mielenkiintoisimmat. Niitä voidaan
pinota useampia peräkkäin
ajettaviksi. Se, mitä suodattimia ajetaan, on sidottu "named queryihin".
Jokaista named queryä kohti on mahdollista sitoa tietty setti suodattimia.
Sitominen tapahtuu luokassa FI.hut.cs.osprey.common.module.NamedQuery
.
Sen konstruktorissa täytetään hajautusrakenne, avaimena kyselyn nimi ja arvona
suodatinsetti merkkijonona.
Suodatinsetin määrityksen muoto on
pakkaus.EnsimmäinenSuodatin(sana=vakioarvo,toinensana=toinenarvo);
pakkaus.ToinenSuodatin(sana=arvo,jokumuu=?profiilista?);
Arvot, jotka tulee antaa kaikille suodattimille, ovat lowdrop, highpass ja
weight. Muut arvot riippuvat suodattimesta.
lowdrop | pistemäärä, jota pienemmät pisteet kyseisestä suodattimesta saaneet eivät pääse läpi seuraavalle suodattimelle, eivätkä myöskään koko suodatinsetistä | kokonaisluku 0..100, < highpass |
highpass | pistemäärä, jota suuremmat pisteet saaneet pääsevät automaattisesti läpi suodatinsetistä, riippumatta seuraavien suodatinten antamista pisteistä | kokonaisluku 0..100 > lowdrop |
weight | painoarvo, jolla kyseinen suodatin vaikuttaa kokonaispisteisiin. Eri suodatinten antamista pisteistä lasketaan siis painotettu keskiarvo. | kokonaisluku > 0 |
Määrityksessä voidaan antaa myös käyttäjäkohtaisia arvoja,
jotka merkitään kysymysmerkein ympäröidyllä
sanalla. Asiakasohjelmistossa voidaan profiilinmuokkaussivulla antaa filttereihin
liittyville avainsanoille arvoja: profiilista=yy/kaa/koo/nee,. Tämä saa
jälkimmäisestä suodatinmäärittelystä aikaan seuraavanlaisen:
pakkaus.ToinenSuodatin(sana=arvo,jokumuu=yy/kaa/koo/nee)
;
Suodattimet instantioidaan luokassa FI.hut.cs.osprey.common.filter.FilterEngine
.
Se ottaa vastaan suodattimia, jotka perivät abstraktin luokan
FI.hut.cs.osprey.common.filter.Filter
. Kun määritellään uusi suodatin, on
toteutettava abstrakti metodi int filter(VObject object)
. Sen tulee palauttaa
suodatettavalle oliolle pistemäärä 0..100. Se, miten pisteytys varsinaisesti
tapahtuu on täysin sovelluskohtaista. Mikäli kyseinen suodatin ei osaa
suodattaa sille annetun tyyppisiä olioita, sen kuuluu heittää
FI.hut.cs.osprey.common.filter.FilterTypeException
.
Mikäli suodatin tarvitsee muita parametreja
kuin yllä luetellut pakolliset, on ne alustettava init-metodissa. Kun määritellään
korvaava init
-metodi, on suositeltavaa, että se kutsuu isäluokkansa
init
-metodia, joka alustaa vakioparametrit.
Alla on esimerkki yksinkertaisesta suodattimesta. Se arpoo luvun 0..100,
ja mikäli se on pienempi kuin parametrissa limit
annettu arvo, annetaan 0 pistettä, muuten annetaan juuri arvottu pistemäärä.
01: public class RandomFilter extends Filter { 02: 03: private int limit = 0; 04: 05: public int filter(VObject object) throws FilterTypeException { 06: java.util.Random rand = new java.util.Random(); 07: int rndNum = rand.nextInt(100); 08: if (!object instanceof VEvent) 09: throw new FilterTypeException(); 10: if (rndNum < limit) 11: return 0; 12: else 13: return rndNum; 14: } 15: 16: public void init(Map properties, Core core) throws FilterTypeException { 17: super.init(properties, core); 18: try { 19: String lim = (String)properties.get("limit"); 20: if (lim != null) 21: limit = String.parseInt(lim); 22: } catch (Exception e) { 23: throw new FilterTypeException(); 24: } 25: } 26: }
Rivillä 1 kerrotaan suodattimen perivän abstraktion luokan Filter, kuten kaikkien suodatinten täytyy.
Rivillä 8-9 tarkastetaan, että suodatettava olio on tyyppiä, jota
suodattimemme ymmärtää. Mikäli näin ei ole, heitetään poikkeus
FilterTypeException
Riveillä 10-13 lasketaan oliolle annettavat pisteet. Mikäli laskentakaava mahdollistaa pisteitä alle nollan ja yli sadan, on ne muunnettava ko. välille.
Rivillä 16 init-metodi kutsuu isäluokkansa init-metodia. Se alustaa kaikille suodattimille yhteiset parametrit
Riveillä 19-21 pyydetään suodattimen tarvitsemat parametrit taulukosta. Mikäli tarvittavaa parametria ei löydy, voidaan turvautua vakioarvoihin tai vaihtoehtoeisesti heittää poikkeus, mikäli suodatin ei voi toimia ilman ko. parametria.
Harjoitustyössä toteutettiin kaksi suodatinta, joista toinen on
FI.hut.cs.osprey.common.filter.ProximityFilter
. Se suodattaa tapahtumia sen
perusteella, kuinka kauan niihin siirtyminen kestäisi nykyisestä sijainnista.
Tarvittavat parametrit kaikille yhteisten lisäksi:
latitude | Vertailusijainnin (esim. käyttäjän nykyisen sijainnin) leveyspiiri | Asteita desimaalilukuna |
longitude | Vertailusijainnin pituuspiiri | Asteita desimaalilukuna |
minutes | Jos siirtymiseen kuluu tasan minutes minuuttia,
annetaan limitpoints pistettä. Yo. kuvassa pisteen
A x-koordinaatti. |
Kokonaisluku > 0 |
limitpoints | Pistemäärä, joka annetaan kun siirtymiseen kuluu tasan
minutes minuuttia. Pisteen A y-koordinaatti. |
Kokonaisluku 0..100 |
zerominutes | Siirtymiseen kuluva aika, jolloin annetaan nolla pistettä. Pisteen B x-koordinaatti. | Kokonaisluku > minutes |
Yllä lueteltujen pisteiden välillä
pistemäärä interpoloidaan siten, että hetkellä
0 annetaan 100 pistettä.
Jälkimmäinen suodatin, WordFilter
, suodattaa tapahtumia siinä esiintyvien sanojen
perusteella. Asiakasohjelmistossa voidaan määritellään esim. parametri
words=computer:10/programming:20/car:-20
jolloin aina kun tapahtuman summary
tai description -kentistä löytyy joku kyseisistä sanoista, sen pistemäärään lisätään
määrityksessä sanan perässä sille annettu pistemäärä.
Esim. yllä olevalla määrityksellä tapahtuma:
"Summary: Lecture in computer programming, Description:
Topics car and cdr." saisi 10+20-20=10
pistettä.
Sekä kalenteripalvelin, että asiakasohjelmisto käyttävät samaa toteutusta CAP-protokollasta. CAP-protokolla tuki ei ole täydellinen, joten jatkokehityksessä saattaa tulla tarve täydentää tuettuja ominaisuuksia. CAP:sta puuttuu mm. tuki käyttäjätietojen välityksiin, koska protokolla keskittyy vain itse kalenterimerkintöjen siirtoon. CAP-protokolla on myös hyvin monimutkainen, mikä varmasti hidastaa sen käyttöönottoa (tai jopa estää sen).
CAP-protokollajäsennin on toteutettu käyttäen
JavaCUP:lla.
Selaimena toimii JLex.
Kielioppi löytyy Java-paketin Fi.hut.cs.osprey.common.cap
alta tiedostosta
parser.cup
.
Lekserin määritys löytyy vastaavasta paketista tiedostosta lexer.lex
.
CAP-parseri luo suoraan Java-paketissa FI.hut.cs.osprey.common.icalendar
olevia iCalendar-olioita. Vastaavasti iCalendar-oliot pystyvät tuottamaan CAP:n
mukaisen esityksen itsestään toString
-metodilla.
Sekä asiakasohjelmisto että palvelin käyttävät edelleen samasta paketista löytyvää
CAPParser
-luokkaa, joka edelleen käyttää JavaCUP:n luomaa
parseriluokkaa. Palvelimen CAP-tuki löytyy luokasta
FI.hut.cs.osprey.server.parser.CAPRequestParser
. Vastaavasti CAP-yhteyden
asiakaspää löytyy luokasta FI.hut.cs.osprey.common.cap.CAPClient
.
CAP-yhteydet voivat olla luonteeltaan persistenttejä ts. sama yhteys palvelee
useampaa saman käyttäjän palvelupyyntöä. Palvelin implementaatio ei kuitenkaan
tue tällaisia persistenttejä yhteyksiä, vaan CAP-yhteydet on rajoitettu yhteen
palvelupyyntöön. Rajoitus juontuu sekä CAPClient
- että CAPParser
-toteutuksesta. Yhteyden persistentiksi muuttaminen vaatii siis molempien muuttamista
ts. serveripäähän palvelusilmukan muodostamista ja asiakasohjelmistoon yhteyden sulkematta
jättämisen. Servlet-käytössä TCP-yhteyksien aukipitäminen ei kuitenkaan ole välttämättä
paras mahdollinen idea, johtuen servlettien transientista luonteesta.
CAP mahdollistaa useita eri autentikointimahdollisuuksia käyttäjälle mm. Kerberoksen. Lisäksi on mahdollista käyttää esim. salattuja TCP-yhteyksiä ns. SSL:ää käyttäen. Kaikki nämä seikat liittyvät kuitenkin vain CAP-yhteyden alussa suoritettavaan kättelyyn asiakasohjelmiston ja palvelimen välillä. Joten vain edellä mainitut asiakasohjelmiston ja palvelinpuolen toteuttavat luokat vaativat muutoksia.
Nykyinen autentikointimenetelmä on Osprey-projektin oma ja perustuu yksinkertaisesti käyttäjän tunnuksen ja salasanan selväkielisenä lähetykseen palvelimelle.
Tietokantaoperaatiot suoritetaan keskitetysti Java-paketin
FI.hut.cs.osprey.common.repository
alta. Paketissa on kaksi
tietokantaa käsittelevää luokkaa, sillä käyttäjien profiilitietueet
ja itse kalenterimerkinnät käsitellään kukin omissa luokissaan.
Kummastakin Java-luokasta löytyy metodi getConnection
:
private Connection getConnection(String url, String user, String password) throws SQLException;Metodia kutsutaan luokissa aina, kun halutaan saada käyttöön JDBC-pohjainen tietokantayhteysolio
java.sql.Connection
. Metodin parametrit
noudattelevat standardia JDBC-formaattia. Lisätietoja JDBC:stä löytyy
täältä.
getConnection
-metodin yhteydenhakutapaa muuttamalla voidaan
implementoida tietokantayhteyksien pooli ja siten huomattavasti tehostaa
tietokantaoperatioita. Oletusarvoinen implementaatio avaa aina
uuden yhteyden JDBC-tietokantaan, mikä on verrattain hidas operaatio. Poolin
avulla yhteyksien avausta ei tarvitse suorittaa joka kantaoperaation yhteydessä.
Asiakasohjelmiston ja kalenteripalvelin lisäksi ohjelmistosta löytyy pieni komentorivityökalu, jolla voidaan päivittää käyttäjän sijainti kalenteripalvelimella. Tämä soveltuu käytettäväksi esimerkiksi juuri Mediapolin WLAN-verkossa.
Toimintaperiaate on seuraavanlainen:
Käyttäjän päätelaite tarvitsee siis säännöllisin väliajoin suoritettavan oman pienen Java-ohjelman, joka ottaa TCP-yhteyden käyttäjän kalenteripalvelimeen. Käyttäjän sijaintia ei voida siis päivittää automaattisesti ellei ko. työkalu ole säännöllisesti kertomassa uudesta sijainnista (location update). Käyttäjä voi kuitenkin päivittää sijaintinsa tällöinkin manuaalisesti.
Samoin asiakasohjelmiston on itse päivitettävä käyttäjän päätelaitteen paikka palvelimelta, jos käytössä ei ole jonkinlaista push-tekniikkaa. Osprey-projektin puitteissa toteutettu asiakasohjelmisto ei automaattisesti päivitä käyttäjän paikkaa, vaan käyttäjän on itse ladattava karttasivu uudelleen hakeakseen paikkatietonsa palvelimelta.
Sekä ko. työkalu, että vastaava osa palvelimesta löytyvät Java-paketista
FI.hut.cs.osprey.common.directory
.
Kalenteri lähettää käyttäjälle hälytyksiä tapahtumista ja todo-merkinnöistä. Käyttäjä voi määrittää itse ennakon, jolloin hälytys tapahtuu. Mikäli käyttäjä ei ole määrittänyt hälytysennakkoa, palvelin päättelee käyttäjän sijainnista koska on aika suorittaa hälytys.
Palvelimen hälytyskäyttäytyminen on toteutettu Java-paketissa
FI.hut.cs.osprey.watcher
. Moduuli WatcherModule
suorittaa
hälytyksen tapahtumiin ja todoihin merkittyjen hälytysennakoiden mukaan käyttäen
saatavilla olevia hälytysmekanismeja. Moduuli PredictModule
luo
merkintöihin hälytyksiä ennakoiden käyttäjän sijaintia suhteessa tulevaan tapahtumaan,
mikäli käyttäjä ei ole hälytysennakkoa merkintään tehnyt.
Palvelimessa on toteutettuna lyhytsanomia (SMS) lähettävä hälytin. Hälyttimiä voi tehdä tarpeen mukaan helposti lisää esim. email-hälyttimen. Hälyttimien pitää toteuttaa vain alla oleva rajapinta, jonka kautta sisään tulee niin tieto hälytyksen kohteesta kuin aiheuttajasta.
public interface Alerter { /** * Send an alarm to the target user about the event * or the todo. */ public void alert(Target t, VEventTodoParent v); }
Java-paketista FI.hut.cs.osprey.common.watcher.sms
löytyy HTTP-asiakasohjelmisto,
joka lähettää hälytyksen HTTP-palvelimelle. Useat kaupalliset SMS-viestintäalustat mahdollistavat
viestien lähetyksen HTTP:llä. Ko. paketin luokkia modifoimalla voidaan nykyinen hälytintoteutus
muuntaa lähes mille tahansa em. rajapinnan tarjoavalle SMS-palvelulle.
Esimerkin vuoksi kuvataan yksinkertaisen sähköpostilla hälytyksen lähettävän hälyttimen teko.
Käyttäjän sähköpostiosoitetta ei talleta profiilitietoihin. Tämän muuttaminen vaatii seuraavia toimenpiteitä:
VProfile
-luokkaan on lisättävä attribuutti osoitteelle vrt.
String phonenumber
.
VProfile
-luokasta löytyvät kantaoperaatioiden kyselyiden
muodostusmetodeja read
, write
ja delete
on muutettava käsittelemään ko. uutta attribuuttia.
parser.cup
-
tiedostoon ja lexer.lex
-tiedostoon. VProfile
-osuuksia katsomalla
ko. tiedostoista selviää nopeasti kääntäjiä ennen tehneelle henkilölle, miten laajennus
voidaan tehdä, joten yksityiskohtia ei tässä näytetä.
ProfilePage
.
Kalenterin perustoiminnallisuus on kapsuloitu CalendarModule
-rajapintaan,
tällä hetkellä toiminnallisuuden toteuttaa CalendarOperationModule
-luokka.
Se hoitaa aivan perustoiminnallsuuden: halutun kalenterin haun, jalostajien
kutsumisen, muokatun käskyn välittämisen kalenterille ja suodatuksen
tulosjoukolle. Se on siis pelkästään työnjakaja, joka kutsuu muita moduuleja.
Tarkka toiminnallisuus on kuvattu alla.
Työnkulku CalendarOperationModule :ssa1. Tarkistetaan komennon oikeellisuus 2. Hankitaan käskyn lähettäjän profiili 3. Suoritetaan jalostajat rekisteröintijärjestyksessä 4. Toimitaan käskyn tyypin mukaisesti READ. Lähetetään pyynnöt kohdekalentereille ja filtteröidään tulosjoukko CREATE. Lähetetään minimiversio pyynnöstä (aika) kohdekalentereille uid:n selvittämiseksi. Tehdään UPDATE koko tiedoilla. UPDATE. Lähetetään pyyntö kohdekalenterille. DELETE. Lähetetään pyynnöt kohdekalentereille. |
Itse älyominaisuudet on toteutettu jalostajamoduuleissa. Uuden
ominaisuuden lisääminen tapahtuu luomalla uusi jalostajamoduuli, johon
haluttu älykkyys ohjelmoidaan. Sen jälkeen moduuli lisätään vain
ladattavaksi serverille (FI.hut.cs.osprey.server.CalendarServer
)
ja ominaisuus on kytkeytynyt päälle. Kalenteriarkkitehtuurin muihin
luokkiin ei tarvitse koskea.
Esimerkki uuden jalostajamoduulin luomisesta löytyy kohdasta 8.7.1.
Harjoitustyössä toteutettiin vain hyvin yksinkertainen hakemistopalvelu,
josta voidaan kysellä tietyllä alueella sijaitsevia kalentereja. Tavoitteena
oli kuitenkin tehdä rajapinta, joka voitaisiin toteuttaa myös monimutkaisemmalla
toteutuksella, esimerkiksi hajautetulla hierarkisella rakenteella DNS:n
tyyliin. Toteutetttava rajapinta on FI.hut.cs.osprey.common.directory.Directory
.
Siinä rekisteröitävien olioiden on toteutettava
FI.hut.cs.osprey.common.directory.Description
rajapinta, eli tällä hetkellä
ne ovat joko luokkaa ClientDescription
, joka tarkoittaa jonkun asiakasohjelmiston
kuvausta, tai CalendarDescription
, joka tarkoittaa jonkin kiinteämmän paikan
kalenteria.
Kun kysellään vaikkapa Innopolin sijainnilla kilometrin
säteellä olevia kalentereita, metodi Description[] get(GeoPosition position,
int radius, int type)
voisi siis aloittaa kyselyn maailman juurisijaintipalvelimelta. Tämä osaisi
palauttaa palvelimen, joka vastaa esim. Euroopan sijanneista, tämä taas Suomen,
tämä taas Espoon. Espoon palvelin saattaisi palauttaa sekä Otaniemen, että
Tapiolan lokaatiopalvelimet, joilta sitten saadaankin varsinainen vastaus.
Kullakin lokaatiopalvelimella olisi keskussijainti sekä ympyrän säde,
josta kyseinen palvelin vastaa.
Koska usein tarvitaan myös vastakkaissuuntaista
kyselyä, eli "missä tämä kalenteri sijaitsee",
GeoPosition getPosition(Description obj)
,
täytyy myös sellainen toteuttaa.
Koska kalentereja kuvataan niiden URLeilla, on kyseisen palvelimen osoite siis
tiedossa. Silloin voitaisiin sijaintikysely sisällyttää itse kalenteripalvelimeen.
Myös erillinen lokaatiopalvelu voidaan toteuttaa samalla tyylillä kuin reverse
DNS. Tämäkin toiminnallisuus piilotetaan Directory
-rajapinnan taakse, joten
kysyjän ei tarvitse tietää, miten hakemisto on toteutettu. Register ja unregister
metodit toteutetaan samalla hierarkialla kuin hakukin.
Palvelimen moduulit kommunikoivat keskenään ytimen välityksellä. Toisin sanoen palvelimesta löytyy keskeinen kohta, joka on vastuussa kaikesta kommunikaatiosta palvelimen sisällä. Tätä hyväksi käyttäen palvelin prosessi on mahdollista hajauttaa useampaan prosessiin. Muutaman käyttäjän järjestelmässä tähän tuskin tulee tarvetta, mutta koska älykkäät kalenterioperaatiot vaativat kohtuullisesti laskentatehoa, käyttäjämäärän lisääntyessä tähän tulee varmasti tarvetta.
Moduulit pyytävät ytimeltä, joka toteuttaa rajapinnan
FI.hut.cs.osprey.common.core.Core
. Rajapinnasta löytyy metodit
niin moduulien rekisteröintiin ytimeen, kuin moduulien hakuun. Hajautus
voitaisiin toteuttaa seuraavien vaiheiden mukaisesti:
Yllämainitulla tavalla itse moduulien toteuksiin ei tarvitse koskea, mutta palvelin prosessi voidaan hajauttaa usealle koneelle. Mikäli halutaan kehittyneempiä hajautusmenetelmiä vrt. kuormanjakoa (load-balancing) klusterin sisällä, voidaan proxyjen toteutusta muuttaa siten, että proxyt tajuavat useamman saman moduulin palveluja tarjoavan palvelimen läsnäolon ja käyttävät esim. vähiten kuormitettuna olevaa.
Mikäli halutaan esimerkiksi analysoida käyttäjien tapoja käyttää kalenteria, on luontevin tapa lähestyä ongelmaa toteuttaa erillinen palvelin ohjelmiston lokitiedosto(j)a analysoiva työkalu.
Työkalun tehtävää voidaan helpottaa lisäämällä vakio lokitiedoston rinnalle toinen, erityisesti analyysejä varten ulkoasultaan optimoitu lokitiedosto. Log4J mahdollistaa useampien lokitiedostojen rinnakkaisuuden, ja jokaisella lokitiedostolla voi olla oma konfiguraatio mm. erilainen ulkoasu. Lisää tietoja lokitiedostojen lisäämisestä ja ulkoasujen konfiguroinnista löytyy Log4J:n kotisivuilta.
Analyysejä varten todennäköisesti kiinnostavimmat lokimerkinnät
syntyvät CalendarOperationModule
:ssa, joten saattaa
edelleen olla hyödyllistä rajoittaa analyysilokiin tulostettavaksi
ainoastaan merkinnät ko. luokasta. Luokkahan pitää sisällään
kalenterioperaatioiden älyn ts. logiikan ja kaikki kalenterimerkinnöille
tehtävät operaatiot matkaavat ko. luokan lävitse.
Kalenteripalvelin ei tarjoa erillistä käyttäjähallintarajapintaa lukuunottamatta käyttäjien profiilien muuttamista. Tästä johtuen käyttäjien ts. kalenterien lisäys palvelimeen on tehtävä suoraan kantaan SQL-operaatioina.
insert into target values('kalenteri', 'salasana');
delete from target where target = 'kalenteri';
update target set auth = 'uusisalasana' where target = 'kalenteri';
Kalenterin nimeä ei voida muuttaa ts. kalenteri on tuhottava ja luotava uudestaan uudella nimellä mikäli nimi halutaan vaihtaa.
Kun kalenteri ts. käyttäjä on lisätty tietokantaan, kalenteri on käyttäjälle valmis käytettäväksi. Palvelin luo muut tarvittavat tietueet lennossa käyttäjän sisäänkirjoittautuessa ensimmäisen kerran.
Koska toteutettu käyttöliittymä on tehty WWW-selaimella käytettäväksi, se on suhteellisen helppo muokata mille tahansa laitteelle, joka osaa hakea ja näyttää WWW-sivuja.
Käyttöliittymä on optimoitu täysikokoisilla monitoreilla katsottavaksi. Käyttöliittymä on kuitenkin toteutettu käyttäen koko näyttöä pienempiä kehyksiä (frames), jotka yhdessä tai erikseen näyttävät eri toimintoja. Alla olevassa esimerkkikuvassa on neljä kehystä:
Toteutus voidaan muokata PDA:lle sopivaksi. Tässä oletetaan, että
PDA:n näyttö on pienempi ja suhteellisesti kapeampi kuin normaali
monitori. Tällölin kehyksistä voidaan poistaa oikeanpuoleinen, ja
vasemmanpuoleinen voidaan siirtää ylävalikkopalkin alle. Kehykset on
määritelty luokissa FrontFrame
,
CalendarFrame
, TodoFrame
,
MapFrame
ja SettingsFrame
.
Tämän jälkeen kaikki HTML-ohjaukset oikeanpuoleiseen kehykseen
kannattaa ohjata keskimmäiseen kehykseen. Esim. linkki <A
HREF="..." TARGET="right"> muuttuisi muotoon
<A HREF="..." TARGET="center">. Jotkin
linkit on syytä poistaa kokonaan. Esim. CalendarFrame
näyttää keskimmäisessä kehyksessä käyttäjän tapahtumat ja
oikeanpuoleisessa kehyksessä lähialueen tapahtumat. Jos jälkimmäinen
määrittely ohjataan center
-kehykseen, sisältö
kirjoittautuisi käyttäjän tapahtumien päälle, joten linkki pitää
poistaa PDA:lle konvertoitaessa. Tällaiset poistettavat linkit eivät
kuitenkaan aiheuta toiminnallisuuden menetystä, sillä saman sisällön
voi saada näkyviin toistakin kautta. (Tässä tapauksessa esim.
karttasivun kautta.)
Näiden muutosten jälkeen selainikkunan korkeus on suurempi kuin leveys, jolloin se sopii paremmin PDA:lla näytettäväksi. Myös fonttikoon ja kehysten suhteellisten kokojen muutoksilla voidaan helposti vaikuttaa selainikkunan sopivuuteen PDA:n näytölle.
Java-paketista FI.hut.cs.osprey.common.importer
löytyvä
komentorivipohjainen kalenterimerkintöjen sisääntuoja on periaatteeltaan
yksinkertainen:
event.dtd
:n rajoituksien mukaan. DTD:ssä on nimestä
huolimatta määritelty rakenne sekä Todo- että tapahtumamerkinnöille.
Alla ohjelmiston ajon, ilman parametrejä, tulostamat käyttöohjeet:
Usage: <XML-file> <default target calendar> <default target password> <IP of calendar server> <port of calendar server>Yllä target tarkoittaa jälleen käytännössä käyttäjää tai paikannimeä ts. kalenterin nimeä.
Komentorivityökalun on tarkoitus toimia pohjana monipuolisemmalle liitynnälle jo olemassa olevaan kalenteriratkaisuun. Mikään ei rajoita toteuttamasta myös muita kalenterioperaatioita kuin merkintöjen lisäystä em. tapaan.
Alla olevat toiminnallisuus- ja vaatimusmäärittelyissä mainitut ominaisuudet ovat jääneet toteuttamatta johtuen projektin aikana suoritetusta priorisoinnista - jo määrittelyjä tehdessä asiakkaan kanssa tiedettiin että kaikkia ei pystytä millään toteuttamaan. On huomattava, että puuttuvat ominaisuudet ovat verrattain pieniä osia koko arkkitehtuurista.
Asiakasohjelmisto:
Kalenteripalvelin:
Olemassaolevat moduulit eivät tällä hetkellä käsittele saamiaan
internet-osoitteita mitenkään, eivätkä siten osaa yhdistää vaikka esimerkiksi
foo.bar.com
:n ja calendar.zak.net
:n olisi sama kone.
Nimien käyttö ristiin voi aiheuttaa kalenterien/profiilien löytymättömyyksiä.
Tämä pitäisi varmaankin korjata siirtymällä numeeristen osotteiden
käyttöön.
Toteutetun käyttöliittymän suurin ongelma on Java-grafiikkametodien
riippuvuus todellisesta grafiikkaympäristöstä. Toteutus siis vaatii
käynnissä olevat X-ympäristön, jotta esim.
java.awt.Graphics
-luokan kuvamanipulaatiometodeja voisi
käyttää, vaikka käyttöliittymä itsessään ei X-ympäristöllä mitään
teekään. Sun Microsystemsin Java-versiot ennen versiota 1.4 eivät tue
ns. headless-grafiikkaa, jolloin kuvia voi muokata myös ilman
käynnissä olevaa X-ympäristöä.
Toteutettu käyttöliittymä vaatii siis toimiakseen X-palvelimen, johon
käyttöliittymäservletti voi ottaa yhteyden. Servletin ajoympäristölle
(esim. Apache Jakarta-Tomcat) on kerrottava
DISPLAY
-ympäristömuuttujan avulla, mistä X-palvelin
löytyy. Jos X-palvelinta ajetaan samassa koneessa kuin
käyttöliittymäservlettiä, tämä voidaan tehdä esim. lisäämällä
servlet-ajoympäristön käynnistysskriptiin rivi: export
DISPLAY=:0
Tietokantaoperaatiot eivät käytä PostgreSQL:n mahdollistamia
sekvenssejä uniikkien tunnisteiden allokointiin, koska PostgreSQL:n
JDBC-ajurit eivät tue ko. ominaisuutta. Tarvittava koodi on
kommentoitu pois luokasta FI.hut.cs.osprey.common.icalendar.Sequence
ja korvattu random
-funktiolla 64-bittisestä lukuavaruudesta.
[OSPREY-K] Osprey-ryhmä, Projekti Ospreyn käyttöohje, kayttoohje.html, viitattu 24.1.2001
[OSPREY-T] Osprey-ryhmä, Projekti Ospreyn tekninen määrittely, tekninenmaarittely.html, viitattu 21.4.2001