@startuml
title Class Diagram
package source {
    interface GestorePrevisioni<<interface>> {
        - previsioni24H: ListaEventi {ordered}
        + GetPrevisioni24H() : ListaEventi
        + SetPrevisioni24H(ListaEventi)
        + GeneraPrevisioni(): ListaEventi {Query}
    }

    class GestorePrevisioniATempo {
        - previsioni24H: ListaEventi {ordered}
        - timer: Timer [1]
        + GetPrevisioni24H() : ListaEventi
        + SetPrevisioni24H(ListaEventi)
        + GeneraPrevisioni(): ListaEventi {Query}
        - CalcolaDifferenze()
    }

    class Sorgente {
        - id: integer [1]
        - timer: Timer [1]
        + InviaPrevisioni(ListaEventi)
    }
    note bottom of Sorgente: Il timer ha una durata di 4h e ogni volta che termina\nviene chiamato il metodo "InviaPrevisioni(previsioni24H)".
    note bottom of GestorePrevisioniATempo: Il timer ha una durata\ndi 5sec e ogni volta che termina\nviene chiamato il metodo "GeneraPrevisioni()".\nSe ci sono degli eventi in corso, vengono\nsubito inviati al ServerImpl attraverso il metodo\n"InviaPrevisioni(EventiInCorso)" di Sorgente.

    GestorePrevisioni "0..1" <-> "1" Sorgente : \t\t\t
    GestorePrevisioni <|.. GestorePrevisioniATempo
}

package server{
    interface "Remote (from RMI)" as Remote <<interface>>

    interface Server<<interface>> {
        + StoreEventi(ListaEventi, Sorgente)
        + GetEventi(FiltroRicerca): ListaEventi {query} {ordered}
    }

    class ServerImpl {
        - sqlConn: Connection  [0..1]
        + StoreEventi(ListaEventi, Sorgente)
        + GetEventi(FiltroRicerca): ListaEventi {query} {ordered}
    }

    class "UnicastRemoteObject\n(from rmi.server)" as UnicastRemoteObject

    Remote <|-- Server
    Server <|.. ServerImpl
    ServerImpl -|> UnicastRemoteObject :\t
}

Sorgente .> Server

package user {
    class Utente {
        - CAPpreferiti: ListaCAP [0..1]
        + SetCapPreferiti(ListaCAP)
        + GetAllarmiInEvidenza(): ListaEventi {query} {ordered}
        + EffettuaRicerca(FiltroRicerca)
    }

    interface GestoreNotifica {
        + NotificaEventi(ListaEventi)
    }

    class GestoreNotificaATempo {
        - timer: Timer
        + ControllaPrevisioni()
        - NotificaEventi(ListaEventi)
    }
    note left of GestoreNotificaATempo: Il timer ha una durata di 10sec\ned ogni volta che termina, viene\neffettuata una query sulle nuove previsioni\nnei cap preferiti dall'utente

    Utente "1" <-> "1" GestoreNotifica :\t
    GestoreNotifica ..|> GestoreNotificaATempo
}

Server <. Utente

package common {
    enum StatoEvento {
        Previsto
        InCorso
        Accaduto
        Rientrato
    }

    class Evento<<dataType>> {
        - id: integer [1]
        - cap: String  [1]
        - sorgente: integer [1]
        - testo: String [0..1]
        - tipo: String [0..1]
        - istanteTemporale: DataTime [1]
        - gravità: integer [1]
    }

    class ListaEventi <<dataType>>

    interface List<<interface>>

    ListaEventi ..|> List: \t
    StatoEvento "1" <- Evento: \tÈ\t
    Evento " * " <-*  ListaEventi: Composta da

    class FiltroRicerca {
        - ListaCAP: ListaCAP [1]
        - Tipo:String [0..1]
        - IstanteTemporale: DateTime [1]
        + SetListaCAP(ListaCAP)
        + GeneraListaCapFromArea(regione:string, provincia:string, città:string)
    }

    class ListaCAP <<dataType>> {
        + CAP: String [*]
    }

    interface Set<<interface>>

    ListaCAP .|> Set :\t
    FiltroRicerca .> ListaCAP
}

'Layout only
hide empty members
skinparam classAttributeIconSize 0
ListaEventi -[hidden] FiltroRicerca
GestorePrevisioniATempo -[hidden]-- StatoEvento
ServerImpl .[hidden].> ListaEventi
@enduml