\section{Metatietomoduuli (RH, KJ)}
\label{metamo}

Luvussa \ref{metaYleis} on kuvattu metatietomoduuli yleisellä tasolla. 
Luvussa \ref{tira_ont} esitellään järjestemän käyttämät ontologiat. 
Luvussa \ref{metaUlko} esitellään metatietomoduulin muille moduuleille tarjoamat palvelut.
Luvussa \ref{metaSisä} kuvataan metatietomoduulin ulkoisten palveluiden toiminta.
Luvussa \ref{metaLuokka} kuvataan metatietomoduulin luokat ja metodit, joskaan ei pseudokooditasolla.

\subsection{Yleiskuvaus}
\label{metaYleis}

Metatietomoduuli luo, ylläpitää ja tallentaa oliomallin käytetyistä ontologioista, ontologialuokkien ilmentymistä ja kuvakorteista. 
Moduuli tarjoaa korkeamman tason palveluja ohjelmiston muille osille. 
Ontologioiden hallintajärjestelmänä käytetään Jena-kirjastoa.
Kuvakortit, ontologiat ja ontologoiden luokkien ilmentymät ovat palvelimen levyllä RDF-muodossa. 
Itse kuvatiedostot ovat erillisessä hakemistossa palvelimen levyllä. Näitten välinen suhde on visualisoitu kuvassa \ref{tira2}. 

\begin{figure}
\begin{center}
\includegraphics[width=0.8\textwidth]{kuva_solmu.eps}
\caption{Kuvakortti joka liittyy kolmeen ontologialuokan, ominaisuuksiensa ja ontologian ilmentymien kautta.}
\label{tira2}
\end{center}
\end{figure}

\subsection{Ontologiat}
\label{tira_ont}
Järjestelmässä on neljä ontologiaa: perusontologia, fasettiontologa, kuvatiedosto-ontologia ja paino-ontologia. Tässä toteutuksessa käytettiin perusontologiana
Avril Styrmanin tekemää promootio-ontologiaa. Se on rakenteeltaan metsä, eli yksinkertaisempi kuin ontologian perusrakenne, suunnattu verkko. 
Tämän vuoksi saattaa toteutuksessa olla ongelmia jotka eivät ilmene käytetyllä perusontologialla. Muut ontologiat kuvattiin luvussa \ref{kuvakortit}. 
Jokaisella perusontologian instanssilla on syytä olla 'Nimi'-atribuutti, joka sisältää instanssin kuvauksen, tai nimenä näkyy instanssin uri.

\subsection{Moduulin ulkoinen rajapinta}
\label{metaUlko}

Tässä luvussa kerrotaan mihin metatietomoduulia käytetään ja miten. 
Metatietomoduulin luokkakaavion löytyy kuvassa \ref{MetaKaavio} ja ontologiaresurssien käsittelyyn tehtyjen työkalujen luokkakaavio kuvassa \ref{ResurssiKaavio}.

\begin{figure}
\begin{center}
\includegraphics[width=1.1\textwidth]{luokat2.eps}
\caption{
Metatiedon luokkakaavio
}
\label{MetaKaavio}
\end{center}
\end{figure}


\begin{figure} 
\begin{center} 
\includegraphics[width=1.0\textwidth]{resourcedia.eps} 
\caption{ 
Ontologiaresurssit
} 
\label{ResurssiKaavio} 
\end{center} 
\end{figure} 

\subsubsection{Mallin luominen ja alustaminen}
Luodaan MuseumModel-olio. Konstruktorin ensimmäisenä parametreina annetaan java.net.URL-olio, jonka sisältämän urlin alta löytyy kuvat sisältävä pictures/kuvatyyppi -hakemistorakenne. 
Kuvatyyppi on kokonaisluku, eli hakemistot ovat \texttt{pictures/0}, \texttt{pictures/1}, jne. Kuvatiedostojen oletetaan löytyvän täältä mikäli niille ei ole annotoitu omaa urlia.
Konstruktorin toisena parametreina annetaan merkkijono, joka sisältää paikallisen hakupolun hakemistoon jonka alta löytyy \texttt{rdf/} ja \texttt{rdf/ontology}- hakemistot.
\texttt{rdf/} -hakemistosta löytyy kuvien annotointidata \texttt{img.rdf}- tiedostossa. 
\texttt{rdf/ontology} -hakemistossa löytyvät ontologiat rdfs-tiedostoissa ja niitten instanssit rdf-tiedostoissa. 

MuseumModel-oliolle kutsutaan readModel()-metodia, joka lukee tiedostot levyltä ja Jenan avulla rakentaa näistä oliomallin.
Mallia ei tarvitse kirjoittaa erikseen levylle, koska se kirjotetaan automaattisesti tunnin väliajoin ja lisäksi kun MuseumModel-olio tuhotaan.

\textbf{Esimerkki}
\begin{verbatim}
MuseumModel model = new MuseumModel(new URL(
    "http://localhost/"), "data/");		
model.readModel();
\end{verbatim}

\subsubsection{HiBrowsen fasettipuiden hakeminen}
Luodusta MuseumModel-oliosta voidaan hakea fasetitpuut hakemalla ensin fasettijuuret MuseumModelin getFacetRoots()-metodilla.
Fasettijuuret ovat OntologyClass-olioita. Tämän jälkeen puut voidaan rakentaa rekursiivisesti kutumalla OntologyClass-olioiden getChildren()-metodia.

\textbf{Esimerkki}
\begin{verbatim}
Iterator facetIterator = 
    model.getFacetRoots().iterator();		
while (facetIterator.hasNext()) {	
    OntologyClass oclass = 
        (OntologyClass)facetIterator.next();
    //..hae tälle juurelle alipuu.
}	
\end{verbatim}


\subsubsection{HiBrowsen suodatuksen käyttö}
Useamman fasetin valinta muodostaa leikkauksen järjestelmän kuvista. 
Leikkaukseen kuuluvat Image-oliot saa kustumalla OntologyClass- luokan getIntersectHash()-metodia halutuilla kuvilla.
Sen jälkeen kokoelma kuvista luodaan OntologyClass- luokan getIntersectImages()-metodilla parametreinaan edellä saatu leikkaus ja haluttu syvyys. 

\textbf{Esimerkki}
\begin{verbatim}
Hashtable intersect = OntologyClass
    .getIntersectHash(model.getAllImages());
Vector pictures = new Vector(
    node.getIntersectImages(intersect, OntologyClass.ALL));
\end{verbatim}

\subsubsection{Kuvaan liittyvien toisten kuvien hakeminen}
Kuvan ominaisuudet haetaan ensin kutsumalla Image-luokan getProperties()- metodia.
Tämän jälkeen selvitetään millä ominaisuuksilla on arvoinaan instansseja. 
Näiltä instansseilta voi kysyä niihin liittyvät kuvat Instance-luokan getImages()-metodilla.

\textbf{Esimerkki}
\begin{verbatim}
Image image = new Image(...);
Vector linkedImages = new Vector();

Iterator iterator = image.getProperties().iterator();
while (iterator.hasNext()) {
    ResourceProperty property = (ResourceProperty)iterator.next();	
    if(property.getValue().isInstance()) {
        Instance instance = property.getValue().getInstance();
        linkedImages.addAll(instance.getImages());
    }
}
\end{verbatim}

\subsubsection{Ontologiaresurssin ominaisuuksien haku}
Ontologiaresurssiin, esimerkiksi kuvaan, liittyviä ominaisuuksia on kahdentyyppisiä. 
On ns. ennaltamääriteltyjä ominaisuuksia joita on jokaisella tietyntyyppisellä ominaisuudella ja 
muita ominaisuuksia joiden olemassaolo vaihtelee resurssin mukaan. 
Ennaltamääritellyillä ominaisuuksilla on omat aksessorinsa, mikäli niitten hakeminen metatietomoduulin ulkopuolelta on järkevää. 
Muita ominaisuuksia haetaan kutsumalla ontologiaresurssia vastavalle oliolle getProperties()- metodia.
Tämä metodi palauttaa vain ne ominaisuudet jotka eivät ole ennaltamääriteltyjä.

getProperties()- metodi palauttaa ResourceCollection-olion jossa on ominaisuuksia edustavia ResourceProperty-olioita.
getNamedProperty()- metodi palauttaa ResourceProperty-olion annetun nimisestä ominaisuudesta tai null jos annetun nimistä ominaisuutta ei ole olemassa.

Saadu(i)sta ominaisuuksista voi kysellä ominaisuuden arvoa getValue()- metodilla. 
Saadulta PropertyValue- olioilta voi kysyä arvon tyyppiä ja itse arvoa. Tarkempaa tietoa löytyy luokkn kuvauksesta luvussa \ref{metaPrVal}.

\textbf{Esimerkki}
\begin{verbatim}
Iterator iterator = resource.getProperties().iterator();
while (iterator.hasNext()) {
    ResourceProperty property = (ResourceProperty)iterator.next();	
    if(property.getValue().isInstance()) {
        Instance instanceValue = property.getValue().getInstance();
    } else if(property.getValue().isLiteral()) {
        String stringValue = property.getValue().getLiteral();		
    }
}
\end{verbatim}

\subsubsection{Painojen käyttäminen}
Ontologiaresursseilla on paino, jota voi lukea ja asettaa tai kasvattaa yhdellä. 
Painoja voidaan käyttää ontologiaresurssien järjestämiseen ja suodatinmoduuli käyttää niitä osana linkkien utiliteettia.
Painot ovat long-tyyppisiä arvoja. 
Painoja voidaan lukea metodilla getWeight(), asettaa metodilla setWeight() ja lisätä yhdellä metodilla addWeight().

\textbf{Esimerkki}
\begin{verbatim}
long weight;
weight = resource.getWeight();
weight = resource.addWeight();
weight = resource.setWeight(weight * 2);
\end{verbatim}

\subsection{Moduulin sisäinen rajapinta}
\label{metaSisä}
Luvussa kuvataan lyhyesti miten luvussa \ref{metaUlko} mainitut operaatiot on toteutettu moduulin sisällä.

\subsubsection{Mallin luominen ja alustaminen}
MuseumModel-luokan konstruktori vain asettaa kentiin annetut url- ja path-arvot.
MuseumModel-luokan loadModel()-metodi käyttää Jenana ModelLoader-luokkaa mallien luomiseksi. 
Malleihin luetaan tietoja toisesta tiedostosta Model-luokan read()-metodilla. 
loadModel()-metodi myös alustaa taustalla toimivan säieen joka on ModelSaver-luokan ilmentymä.
ModelSaver-luokka on MuseumModel-luokan sisäluokka, ja se ajaa run()-metodissaan MuseumModel-olion writeModel()-metodin kerran tunnissa. 
writeModel() ajetaan myös säieen finalize()-metodissa, eli levylle kirjotetaan vielä MuseumModel-olion tuhoamisen yhteydessä.

\subsubsection{HiBrowsen fasettipuiden hakeminen}
MuseumModel-luokan getFacetRoots()-metodi hakee fasettiontologiasta urit faseteille ja hakee näillä ureilla fasettien juuria vastaavat OntologyClass-oliot perusontologiasta.
Juurille haetaan alipuut kutsumalla rekursiivisesti OntologyClass-olioille getChildren()-metodia syvyydellä 0. 
getChildren()-metodi hakee perusontologiasta ne ontologialuokat joiden isänä on kutusuva olio. 
Isä-poika suhdetta kuvataan ontologiassa RDF:n subclassOf-propertylla.

\subsubsection{HiBrowsen suodatuksen käyttö}
Tästä ei ole mitään erityistä sanottavaa. 
Kutsutaan jokaiselle annetulle OntologyClass-oliolle getImages()-metodia ja leikautetaan näitten palauttamat kuvat.
Leikkaus on matemaattisen joukko-opin mukainen leikkaus jossa ei ole kaksoiskappaleita. 
Nopeussyistä leikkaus palautetaan getIntersectHash()-metodista hajautustaulukkona, jolloin yhden fasetin tarkentuessa voidaan nopeammin päivittää jo olemassaolevaa leikkausta.

\subsubsection{Kuvaan liittyvien toisten kuvien hakeminen}
Kuvan \ref{kuvakortit} mukaan kuvakorttiin liittyy aina joukko instansseja ja ontologialuokkia. 
Oletetaan että kaksi kuvaa liittyy sisällöllisesti toisiinsa jos niihin liittyy vähintään yksi yhteinen instanssi. 
Tämä on rajoittunut oletus ja kahden kuvan välisen linkin käsite pitäisi parantaa tulevissa versioissa.

Ominaisuuksien haku ja käsittely on käsitelty alla.

\subsubsection{Ontologiaresurssin ominaisuuksien haku}
Ontologiaresurssiin liittyvät ominaisuudet haetaan perusontologiasta OntologyResource-luokan getProperties()-metodilla.
Metodi hakee kaikki lauseet jotka liittyvät kutsuvan olion ominaisuuksiin, suodattaa niistä pois ns. ennalatamääritellyt ominaisuudet ja yrittää luoda ominaisuuden arvolle Object-olion.
Ominaisuudelle luodaan myös CompositeId-olio ominaisuuden tunnisteeksi. Lopputulos palautetaan ResourceCollection-oliona.

\subsubsection{Painojen käyttäminen}
OntologyResource-luokan addWeight()- ja setWeight()-metodit yrittävät luoda paino-ontologiaan tarvittavat lauseet (statement) mikäli niitä ei kyseiselle resurssille löydy.
Tämän lisäyksen suorittaa metodi addWeightStatements(). 
Jenassa lausetta edustaa StatementImpl-luokka joka on kolmikko joka koostuu kahdesta resurssista subject ja object sekä yhdestä ominaisuudesta property.
Resurssia edustaa luokka ResourceImpl ja ominaisuutta luokka PropertyImpl. Kohde voi olla myös literaali jota edustaa luokka LiteralImpl.
Lause luodaan luomalla ensin kolmikon osat ja kustumalla sitten PropertyImpl-luokan konstruktoria parametrinaan nämä osat. 
Lause lisätään ontologiaan Jenan Model-luokan add()- metodilla. 
Ontologiassa olevaa lausetta muokataan ensin hakemalla se StatementImpl-olioksi ja muokkaamalla se StatementImpl-luokan set()-metodilla.

\subsubsection{ResourceCollectionin muodostaminen}
ResourceCollectionin alaluokka StatementResourceCollection on sikäli erikoinen että tarvittava tieto haetaan Jenan avulla vasta kun se tarvitaan. 
Ainoa tapa päästä kokoelman alkioihin käsiksi on iteraattorilla, joka saadaan kustumalla ResourceCollection-olion iterator()-metodia.
Kun StatementResourceCollection luodaan sen konstruktorille annetaan parametriksi Model-olio mallista josta lauseet haetaan,
SelectorImpl-olio valitsijasta joka suodattaa mallin lauseet ja ResourceProvider-olio joka annetaan sisäluokkana.
Annetun ResourceProvider-olion pitää toteuttaa getResource()-metodi joka luo parametrinaan saamastaan lauseesta halutun OntologyResource-tyyppisen olion.

\subsection{Luokkakuvaukset}
\label{metaLuokka}
Seuraavaksi kuvataan metatietomoduulin luokat, sekä luokkien sisäiset kentät, metodit ja tietorakenteet.

\input{meta_MuseumModel.tex}
\input{meta_WeightComparator.tex}
\input{meta_OntologyResource.tex}

\input{meta_Item.tex}
\input{meta_AbstractItem.tex}
\input{meta_ConcreteItem.tex}
\input{meta_Image.tex}
\input{meta_ImageFile.tex}

\input{meta_OntologyElement.tex}
\input{meta_OntologyClass.tex}
\input{meta_Instance.tex}

\input{meta_PropertyDefinition.tex}
\input{meta_ResourceProperty.tex}
\input{meta_PropertyValue.tex}

\input{meta_ResourceCollection.tex}
\input{meta_SimpleResourceCollection.tex}
\input{meta_StatementResourceCollection.tex}
\input{meta_ResourceIterator.tex}
\input{meta_SimpleResourceIterator.tex}
\input{meta_StatementResourceIterator.tex}

\input{meta_Id.tex}
\input{meta_SimpleId.tex}
\input{meta_CompositeId.tex}
