1400 lines
54 KiB
TeX
1400 lines
54 KiB
TeX
\begin{it}
|
|
\usepackage[italian]{babel}
|
|
\end{it}
|
|
\begin{en}
|
|
\usepackage[english]{babel}
|
|
\end{en}
|
|
|
|
\usepackage[T1]{fontenc}
|
|
\usepackage[utf8]{inputenc}
|
|
\usepackage[pdftex]{graphicx}
|
|
\usepackage{scrlayer-scrpage}
|
|
\usepackage{float}
|
|
\usepackage{hyperref}
|
|
\usepackage{tikz}
|
|
\usepackage[backend=biber]{biblatex}
|
|
\usepackage{pgfgantt}
|
|
\usepackage{pgffor}
|
|
\usepackage{listings}
|
|
\usepackage{lmodern}
|
|
|
|
\bibliography{bibliography}
|
|
|
|
% page margins
|
|
\usepackage[margin=3cm,head=15pt]{geometry}
|
|
|
|
% document metadata
|
|
\begin{it}
|
|
\def\mdtitle{Alternanza scuola-lavoro estesa presso \textit{Agomir S.p.A.}}
|
|
\def\mdsubtitle{Sviluppo di applicazioni multipiattaforma per dispositivi mobili}
|
|
\end{it}
|
|
\begin{en}
|
|
\def\mdtitle{Extended school internship at \textit{Agomir S.p.A.}}
|
|
\def\mdsubtitle{Multiplatform mobile application development}
|
|
\end{en}
|
|
\def\mdauthor{Claudio Maggioni}
|
|
\def\mddate{\today}
|
|
\def\mdrevision{6}
|
|
|
|
% header and footer style
|
|
\clearscrheadfoot
|
|
\pagestyle{scrheadings}
|
|
\makeatletter
|
|
\ohead[]{\mdauthor}
|
|
\ihead[]{\mdtitle}
|
|
\cfoot[\pagemark]{\pagemark}
|
|
|
|
% listings configuration
|
|
\begin{it}
|
|
\renewcommand{\lstlistingname}{Listato}
|
|
\renewcommand{\lstlistlistingname}{Elenco dei listati}
|
|
\end{it}
|
|
\lstset{
|
|
basicstyle=\small\ttfamily,
|
|
frame=shadowbox,
|
|
rulesepcolor=\color{black},
|
|
columns=fullflexible,
|
|
commentstyle=\color{gray},
|
|
keywordstyle=\bfseries,
|
|
escapeinside={\%*}{*)},
|
|
aboveskip=2em,
|
|
captionpos=b,
|
|
abovecaptionskip=1em,
|
|
belowcaptionskip=1em
|
|
}
|
|
|
|
\begin{document}
|
|
|
|
% first page
|
|
\begin{titlepage}
|
|
\pagenumbering{gobble}
|
|
\centering
|
|
\includegraphics[width=0.15\textwidth]{images/logo.jpg}\par\vspace{1cm}
|
|
{\scshape\LARGE Istituto di Istruzione Superiore \mbox{``A. Badoni''}\par}
|
|
\vspace{1cm}
|
|
{\scshape\Large Tesi di maturità\par}
|
|
\vspace{1.5cm}
|
|
{\huge\bfseries\mdtitle\par}
|
|
\vspace{0.75cm}
|
|
{\Large\bfseries\mdsubtitle\par}
|
|
\vspace{2cm}
|
|
{\Large\itshape\mdauthor\par}
|
|
\vfill
|
|
% Bottom of the page
|
|
{\large\mddate\par}
|
|
\begin{it}
|
|
\vspace{0.5cm}
|
|
{\large\textsc{Traduzione in italiano}\par}
|
|
\end{it}
|
|
\vspace{0.5cm}
|
|
{\large\color{red}\textsc{Revisione \mdrevision}\par}
|
|
\end{titlepage}
|
|
|
|
\newpage
|
|
|
|
\pagenumbering{Roman}
|
|
\tableofcontents
|
|
|
|
\newpage
|
|
|
|
\pagenumbering{arabic}
|
|
\begin{it}
|
|
\section{Informazioni generali sul lavoro svolto}
|
|
|
|
A partire dal giorno 19/10/2017, collaboro con l'azienda \textit{Agomir
|
|
S.p.A.}\cite{agomir:website} (produttrice di software, sistemi e servizi per
|
|
piccole e medie imprese) svolgendo un'attività di alternanza scuola-lavoro
|
|
estesa con cadenza settimanale (giovedì e venerdì pomeriggio). Mi occupo di
|
|
sviluppo software di tipo gestionale, nello specifico di applicazioni per
|
|
smartphone multipiattaforma (cioè compatibili sia con Android che con iOS)
|
|
utilizzando strumenti come \textit{Ionic Framework}\cite{ionic:website} e
|
|
\textit{Apache Cordova}\cite{cordova:website}.
|
|
|
|
Tale approccio al mondo \textit{mobile} facilita lo sviluppo, perché al
|
|
posto di usare API e meccanismi legati alla piattaforma \`e possibile
|
|
utilizzare tecnologie note e standard come HTML e Javascript. Naturalmente
|
|
tali applicazioni richiedono pi\`u risorse e tendono ad essere meno fluide,
|
|
ma questo aspetto è meno rilevante in contesti gestionali come quelli
|
|
affrontati da Agomir, non legati ad esempio al mondo dei videogiochi o
|
|
all'elaborazione real-time.
|
|
\end{it}
|
|
\begin{en}
|
|
\section{General information about the work done}
|
|
|
|
Since 19 october 2017, I work with \textit{Agomir S.p.A.}\cite{agomir:website}
|
|
(vendor and producer of software, networking solutions and services for small
|
|
and mid-size
|
|
industries) doing an extended school internship on a weekly basis (thursdays
|
|
and fridays, in the afternoon). I am involved in developing accounting
|
|
software, writing multiplatform smartphone applications (that work
|
|
with both Android and iOS) to be precise. In order to do this, I am using tools
|
|
such as \textit{Ionic Framework}\cite{ionic:website} and \textit{Apache
|
|
Cordova}\cite{cordova:website}.
|
|
|
|
This type of approach to the mobile world makes development more easy because
|
|
instead of using APIs and platform-dependent code it is possible to use
|
|
well-known and standardized technologies such as HTML and Javascript.
|
|
Naturally, these apps require more system resources and they generally are
|
|
less responsive than their native counterparts. However, this aspect is less
|
|
relevant in the world of accounting software that Agomir embraces, far from the
|
|
optimisation hungry sectors of videogames or real time applications.
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\section{Gestione dei progetti}
|
|
|
|
Non ho diretto controllo manageriale su ciò che sviluppo in azienda,
|
|
in quanto ho un ruolo simile a quello di un dipendente. L'incarico di gestire
|
|
l'andamento dei progetti spetta a Mario Goretti, A.D. dell'azienda e capo
|
|
del settore di sviluppo software gestionale (\textsc{SWG}), e ai suoi
|
|
collaboratori.
|
|
|
|
In generale sviluppo i progetti da solo. Collaboro con il collega Daniele
|
|
Crippa per l'interfacciamento con i software aziendali esistenti e per
|
|
l'organizzazione di nuovi progetti, nonché per consigli vari.
|
|
|
|
Nonostante non abbia controllo totale \`e comunque mia responsabilità fare
|
|
stime orarie sul lavoro da svolgere nonché definire passi e \textit{milestone}
|
|
per i vari progetti.
|
|
|
|
Per aumentare la forza lavoro per lo sviluppo di applicazioni \textit{mobile}
|
|
ho coordinato momenti di formazione ad alcuni dipendenti nei quali ho mostrato
|
|
il principale funzionamento delle tecnologie che uso.
|
|
\end{it}
|
|
\begin{en}
|
|
\section{Projects management}
|
|
|
|
I do not directly manage the projects on which I work, because my role is more
|
|
similar to that of an employee. The task of managing the status of the various
|
|
projects is given to Mario Goretti, CEO of the company and head of the
|
|
accounting software department (codenamed SWG), and to his collaborators.
|
|
|
|
In general, I work on the tasks assigned to me alone. I sometimes work with my
|
|
colleague Daniele Crippa in order to interface my projects' code with the
|
|
existing products from the company, to plan new projects, and for suggestions
|
|
in general.
|
|
|
|
In spite of the lack of control I have in regard to the projects I work on, I
|
|
am still responsible for defining development milestones and making
|
|
time estimates for the completion of these.
|
|
|
|
In order to increase the work force assigned to the development of mobile
|
|
apps, I have managed training sessions for some employees in order to show
|
|
them how the tools that I use work.
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\section{Il progetto principale: \textit{InteGRa Mobile}}
|
|
|
|
Questa applicazione, una volta completata, dovrebbe permettere ad utenti in
|
|
mobilità di interfacciarsi con alcune funzioni del prodotto ERP di punta di
|
|
Agomir: il gestionale \textit{InteGRa}\footnote{Sito internet di InteGRa ERP:
|
|
\url{https://integra.agomir.com/}}. Nel dettaglio, sarà possibile accedere
|
|
alle seguenti sezioni:
|
|
|
|
\begin{description}
|
|
\item[Ordini cliente] per registrare ordini di prodotti a clienti;
|
|
\item[Soggetti] per consultare informazioni anagrafiche di clienti e fornitori;
|
|
\item[Agenda] per consultare e aggiungere eventi nel calendario presente
|
|
nell'ERP, il quale si pu\`o integrare con \textit{Outlook};
|
|
\item[Magazzini] gestire e inventariare scorte in magazzino.
|
|
\end{description}
|
|
|
|
In aggiunta, sarà possibile anche registrare le ore per interventi in
|
|
trasferta, funzione gi\`a implementata nell'applicazione
|
|
\textit{InteGRa.Service}, sviluppata nei periodi di alternanza precedenti.
|
|
Tale lavoro non \`e direttamente implementabile in \textit{InteGRa Mobile} a
|
|
causa di differenze consistenti nelle architetture dei due prodotti.
|
|
|
|
Inoltre, l'applicazione sarà in grado di funzionare in modo limitato anche
|
|
senza connessione diretta ad \textit{InteGRa}, permettendo la sincronizzazione
|
|
dei dati modificati con il gestionale in un momento futuro.
|
|
\end{it}
|
|
\begin{en}
|
|
\section{The main project: \textit{InteGRa Mobile}}
|
|
|
|
This app, once completed, will enable moving users to interact with some
|
|
sections of the main ERP product from Agomir: the accounting software
|
|
\textit{InteGRa}\footnote{Website for InteGRa ERP (in italian):
|
|
\url{https://integra.agomir.com/}}. In detail, users will be able to work
|
|
within the following areas:
|
|
|
|
\begin{description}
|
|
\item[Customers' orders] for registering the products customers may order;
|
|
\item[Customers and suppliers] for looking up record data of customers and
|
|
suppliers;
|
|
\item[Calendar] for viewing and editing events on the ERP calendar, syncable
|
|
with \textit{Outlook};
|
|
\item[Warehouses] for managing warehouses and inventories.
|
|
\end{description}
|
|
|
|
In addition to what specified above, users will be able to register working
|
|
hours for business trips. This feature is already implemented in
|
|
\textit{InteGRa.Service}, an app developed in a previous school internship
|
|
period. The two apps can not be merged immediately due to relevant
|
|
differencies in their respective architectures.
|
|
|
|
Finally, the app will be able to work (with limited functionalities) without
|
|
a network link with \textit{InteGRa}, offering data syncronization when a
|
|
connection will be avaliable.
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\subsection{Architettura software}
|
|
\end{it}
|
|
\begin{en}
|
|
\subsection{Software architecture}
|
|
\end{en}
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\resizebox{\ifdim\width>\linewidth\linewidth\else\width\fi}{!}{\input{diagrams/itgmobile}}
|
|
\begin{it}
|
|
\caption{L'architettura di \textit{InteGRa Mobile} raffigurata con un diagramma}
|
|
\end{it}
|
|
\begin{en}
|
|
\caption{The architecture of \textit{InteGRa Mobile} as a diagram}
|
|
\end{en}
|
|
\label{fig:itgmobliearch}
|
|
\end{figure}
|
|
|
|
\begin{it}
|
|
Nella figura \ref{fig:itgmobliearch} si può notare come l'insieme dei
|
|
componenti software all'interno del progetto siano organizzati e comunichino
|
|
tra loro. Tale architettura è stata realizzata da me, basandosi
|
|
sull'esperienza acquisita con il progetto \textit{InteGRa.Service}. Segue
|
|
una spiegazione sintetica (organizzata in punti) del diagramma.
|
|
|
|
\begin{itemize}
|
|
|
|
\item L'applicazione non comunica direttamente con il gestionale, ma tramite
|
|
una serie di chiamate \textsc{REST}\cite{wiki:rest} ad un endpoint lato
|
|
server (chiamato \textit{InteGRaREST}) che svolge il ruolo di intermediario;
|
|
|
|
\item Tale componente è una Java WebApplication che utilizza una libreria
|
|
sviluppata internamente (chiamata \textit{restaurant}) per offrire le rotte
|
|
accessibili al client e per interagire con il database di
|
|
\textit{InteGRa}, una normale istanza di \textit{PostgreSQL};
|
|
|
|
\item Nella fase di comunicazione tramite HTTP, i dati in input vengono
|
|
trasmessi come \texttt{application/x-www-form-urlencoded} mentre
|
|
i dati in output vengono trasmessi come \textsc{JSON}\cite{wiki:json}, e le
|
|
sessioni vengono identificate con un token presente come parametro nella
|
|
query string di ciascuna richiesta;
|
|
|
|
\item \textit{InteGRaREST} effettua autonomamente query \textsc{SQL} al
|
|
database per recuperare velocemente informazioni aventi
|
|
struttura dati e logiche di memorizzazione semplici;
|
|
|
|
\item Nel caso sia necessario interagire con record complessi,
|
|
\textit{InteGRaREST} comunica con \textit{InteGRa} attraverso
|
|
chiamate \textsc{SOAP}\cite{wiki:soap};
|
|
|
|
\item \textit{InteGRa Mobile}, l'applicazione per dispositivi mobili, comunica
|
|
con \textit{InteGRaREST} grazie a una versione client di \textit{restaurant},
|
|
in grado di gestire (in modo limitato) operazioni eseguite in mancanza di
|
|
connessione alla rete.
|
|
|
|
\end{itemize}
|
|
\end{it}
|
|
\begin{en}
|
|
In the picture \ref{fig:itgmobliearch} is shown how the software components
|
|
in the app interact with each other. This architecture was entirely realized
|
|
by me, on the basis offered by the project \textit{InteGRa.Service}. Further
|
|
information is given in the following list.
|
|
|
|
\begin{itemize}
|
|
|
|
\item The smartphone app does not directly communicate with the accounting
|
|
software, but instead it interacts using \textsc{REST} calls\cite{wiki:rest}
|
|
with a middleware server application, named \textit{InteGRaREST};
|
|
|
|
\item The last component mentioned is a Java WebApplication,
|
|
implemented by using an internally developed library named \textit{restaurant},
|
|
that contains the boilerplate needed to generate the \textsc{REST} routes
|
|
and to access the \textit{InteGRa} database, a normal \textit{PostgreSQL}
|
|
instance;
|
|
|
|
\item When information is exchanged by HTTP, input data is encoded
|
|
as the MIME type \texttt{application/x-www-form-urlencoded}, while output data
|
|
is encoded as \textsc{JSON}\cite{wiki:json}. Sessions are identified by
|
|
a token that must be included in the query string of each call;
|
|
|
|
\item \textit{InteGRaREST} queries the database autonomously through
|
|
\textsc{SQL} in order to fetch and store data structures with simple
|
|
or absent logical constraints;
|
|
|
|
\item When interaction with data arranged in complex structures is needed,
|
|
\textit{InteGRaREST} communicates with \textit{InteGRa} through
|
|
\textsc{SOAP} calls\cite{wiki:soap};
|
|
|
|
\item \textit{InteGRa Mobile}, the smartphone app, interacts with
|
|
\textit{InteGRaREST} thanks to a client version of \textit{restaurant},
|
|
which is able to handle offline operations.
|
|
|
|
\end{itemize}
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\subsubsection{\textit{restaurant} -- lato server}
|
|
La libreria \textit{restaurant}\footnote{Il nome \textit{restaurant} è un
|
|
gioco di parole sull'acronimo REST.} viene importata
|
|
come una normale dipendenza Maven\cite{maven:website}. Essa dipende da:
|
|
\begin{description}
|
|
\item[Hibernate ORM\cite{hibernate:website}] un famoso Object/Relation
|
|
Mapper\cite{wiki:orm} per Java, utile ad interrogare il database
|
|
\textit{PostgreSQL} con facilità;
|
|
\item[GSON\cite{gson:website}] una libreria di Google per serializzare
|
|
e deserializzare oggetti Java in JSON;
|
|
\item[Jersey\cite{jersey:website}] un'implementazione dell'API JAX-RS
|
|
per realizzare gli endpoint REST. Ciò avviene senza servlet ma tramite
|
|
semplici metodi contenuti in classi senza ``padre'' dette \textit{controller},
|
|
opportunamente decorati con le annotazioni nel package
|
|
\texttt{javax.ws.rs}.
|
|
\end{description}
|
|
|
|
Le operazioni richieste per interrogare la base di dati sono ulteriormente
|
|
semplificate dal codice contenuto in \textit{restaurant} su due livelli:
|
|
\begin{itemize}
|
|
\item È possibile eseguire normali operazioni di CRUD\cite{wiki:crud}
|
|
nonchè costruire manualmente query tramite i metodi statici della classe
|
|
\textit{CRUDUtils}, che lavorano in input e in output con istanze delle
|
|
classi ``entità'' registrate nell'ORM;
|
|
\item Inoltre, è possibile creare nuovi \textit{controller} con facilità
|
|
ereditando dalle classi astratte \textit{JsonProducer} (per
|
|
implementare funzioni al di fuori di CRUD),
|
|
\textit{ReadableRESTController} (per implementare operazioni in sola
|
|
lettura, equivalenti alla ``Read'' in CRUD) e \textit{CRUDRESTController}
|
|
(per implementare CRUD completi), che offono
|
|
metodi in grado di generare autonomamente risposte in JSON, sia in caso
|
|
di successo che in errore.
|
|
\end{itemize}
|
|
|
|
Seguono le interfacce delle classi \textit{CRUDUtils}, \textit{JsonProducer},
|
|
\textit{ReadableRESTController} e \textit{CRUDRESTController}, complete di
|
|
Javadoc (in inglese, come presente nei sorgenti originali).
|
|
\end{it}
|
|
\begin{en}
|
|
\subsubsection{\textit{restaurant} -- server side}
|
|
The \textit{restaurant}\footnote{\textit{restaurant} is a pun on the word
|
|
\textsc{REST}} library is imported
|
|
as a normal Maven\cite{maven:website} dependency. It requires the
|
|
following dependencies:
|
|
\begin{description}
|
|
\item[Hibernate ORM\cite{hibernate:website}] a famous Java Object/Relation
|
|
Mapper\cite{wiki:orm}, used to query the \textit{PostgreSQL} database
|
|
with ease;
|
|
\item[GSON\cite{gson:website}] a library from Google for serializing and
|
|
deserializing Java object in JSON;
|
|
\item[Jersey\cite{jersey:website}] an implementation of the API JAX-RS
|
|
for creating REST endpoints, not through servlets but using
|
|
simple methods contained in plain classes, called \textit{controllers},
|
|
decorated with the annotations contained in the package \texttt{javax.ws.rs}.
|
|
\end{description}
|
|
|
|
The boilerplate needed to query the database is further simplified by the
|
|
code in \textit{restaurant} on two levels:
|
|
\begin{itemize}
|
|
\item It is possible to perform common CRUD operations\cite{wiki:crud}
|
|
and to build and execute custom queries by the static methods accessible
|
|
in the \textit{CRUDUtils} class. Those procedures work on the ``entity''
|
|
classes registered in the ORM;
|
|
\item In addition to what mentioned above, \textit{controller} can be
|
|
implemented with ease inheriting the abstract classes \textit{JsonProducer} (for
|
|
non-CRUD operations), \textit{ReadableRESTController} (for read-only CRUD
|
|
operations) and \textit{CRUDRESTController} (for complete CRUDs).
|
|
These components offer methods able to automatically generate both success
|
|
and error JSON responses.
|
|
\end{itemize}
|
|
|
|
Below there are the interface listings for the classes \textit{CRUDUtils}, \textit{JsonProducer},
|
|
\textit{ReadableRESTController} and \textit{CRUDRESTController}, with the
|
|
respective Javadoc comments (in english, as in the original sources).
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\def\jsonprdjava-title{Interfaccia della classe \textit{JsonProducer}}
|
|
\end{it}
|
|
\begin{en}
|
|
\def\jsonprdjava-title{Class interface of \textit{JsonProducer}}
|
|
\end{en}
|
|
\begin{lstlisting}[caption=\jsonprdjava-title, label={lst:jsonprd-java}, language=Java]
|
|
/**
|
|
* Something that generates JSON responses
|
|
*/
|
|
public abstract class JsonProducer {
|
|
|
|
protected static final Logger log = %*\ldots*);
|
|
|
|
protected static final Gson GSON = %*\ldots*);
|
|
|
|
/**
|
|
* Generates a json response with status 200 containing an object
|
|
*
|
|
* @param o the contents of the response
|
|
* @return JSON response
|
|
*/
|
|
protected Response jsonResponse(Object o) { %*\ldots*) }
|
|
|
|
/**
|
|
* Generates a json response with custom status containing an object
|
|
*
|
|
* @param o the contents of the response
|
|
* @param status status of the response
|
|
* @return JSON response
|
|
*/
|
|
protected Response jsonResponse(Object o, int status) { %*\ldots*) }
|
|
|
|
/**
|
|
* Generates a json response containing a library standard error
|
|
*
|
|
* @param error the error
|
|
* @return JSON error response
|
|
*/
|
|
protected Response jsonErrResponse(Error error) { %*\ldots*) }
|
|
|
|
/**
|
|
* Generates a json response containing a custom error
|
|
*
|
|
* @param error the error
|
|
* @return JSON error response
|
|
*/
|
|
protected Response jsonErrResponse(ErrorDetails error) { %*\ldots*) }
|
|
|
|
/**
|
|
* Generates an error response if the parameter given as argument
|
|
* is null or an empty string
|
|
*
|
|
* @param s parameter
|
|
* @param propName parameter name, used in the error description
|
|
* @return JSON error response or null if the parameter is valid
|
|
*/
|
|
protected Response require(Object s, String propName) { %*\ldots*) }
|
|
}
|
|
\end{lstlisting}
|
|
\begin{it}
|
|
Per una migliore lettura del listato \ref{lst:jsonprd-java}, si precisa che la
|
|
classe \textit{Error} è una enumerazione Java contenente messaggi di errore
|
|
standard. La classe \textit{ErrorDetails}, invece, permette al codice esterno
|
|
di realizzare messaggi di errore personalizzati. Inoltre, l'oggetto statico
|
|
\texttt{GSON} di classe \textit{Gson} è il serializzatore a JSON offerto dalla
|
|
libreria omonima.
|
|
\end{it}
|
|
\begin{en}
|
|
For a better reading of the listing \ref{lst:jsonprd-java}, it is necessary to
|
|
consider that the \textit{Error} class is a Java enumeration containing error
|
|
messages thrown by the library. In addition, the \textit{ErrorDetails} class
|
|
enables external code to create custom error messages. Finally, the static
|
|
object \texttt{GSON} of class \textit{Gson} is the JSON serializer offered by
|
|
the library of the same name.
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\def\rdbrestjava-title{Interfaccia della classe \textit{ReadableRESTController}}
|
|
\end{it}
|
|
\begin{en}
|
|
\def\rdbrestjava-title{Class interface of \textit{ReadableRESTController}}
|
|
\end{en}
|
|
\begin{lstlisting}[caption=\rdbrestjava-title, label={lst:rdbrest-java}, language=Java]
|
|
/**
|
|
* A REST Controller only readable
|
|
* @param <T> The readable entity class
|
|
*/
|
|
public abstract class ReadableRESTController<T extends Readable,
|
|
U extends PrimaryKey<T>> extends JsonProducer {
|
|
|
|
/**
|
|
* Interface used to carry a function capable of filtering a list
|
|
* of entities after it has been retrieved from the database
|
|
*
|
|
* @param <T> The readable entity class
|
|
*/
|
|
public interface ListFilter<T extends Readable> {
|
|
List<T> filter(List<T> toFilter);
|
|
}
|
|
|
|
/**
|
|
* Returns the class of the readable entity. Used as parameter for
|
|
* CRUDUtils
|
|
*
|
|
* @return the class of the readable entity
|
|
*/
|
|
protected abstract Class<T> getBeanClass();
|
|
|
|
protected final Logger log = %*\ldots*);
|
|
|
|
/**
|
|
* Returns a response with a standard unfiltered, unpaginated list
|
|
* of entities
|
|
*
|
|
* @return JSON response, success or not
|
|
*/
|
|
protected Response list() { %*\ldots*) }
|
|
|
|
/**
|
|
* Returns a list of entities, customizable in many ways
|
|
*
|
|
* @param filter map of names of fields and their values which must
|
|
* be equal in the fetched entities (null accepted if
|
|
* not used)
|
|
* @param otherFilter list of additional filters (Hibernate Criterion
|
|
* objects, null accepted if not used)
|
|
* @param order order of the entities (Hibernate Order, null accepted
|
|
* if not used)
|
|
* @param afterDb implementation of interface containing a function
|
|
* capable of filtering a list of entities (null accepted
|
|
* if not used)
|
|
* @param page the page number to fetch (starts at 1, null accepted
|
|
* if not used)
|
|
* @return JSON response, success or not
|
|
*/
|
|
protected Response list(Map<String, Object> filter,
|
|
List<Criterion> otherFilter, Order order,
|
|
ListFilter<T> afterDb, Integer page) { %*\ldots*) }
|
|
|
|
/**
|
|
* Returns a response with a single entity given its primary key
|
|
*
|
|
* @param filterOne map of names of columns and their values containing
|
|
* the primary key
|
|
* @return JSON response, success or not
|
|
*/
|
|
protected Response get(Map<String, Object> filterOne) { %*\ldots*) }
|
|
|
|
/**
|
|
* Returns a response with a single entity given its primary key
|
|
*
|
|
* @param pk the primary key
|
|
* @return JSON response, success or not
|
|
*/
|
|
protected Response get(PrimaryKey<T> pk) { %*\ldots*) }
|
|
|
|
/**
|
|
* Returns the existing primary keys given a set of primary keys sent
|
|
* as a JSON array
|
|
*
|
|
* @param requestBody the request body with JSON data
|
|
* @return JSON array of the existing primary keys or error response
|
|
*/
|
|
protected Response existing(InputStream requestBody) { %*\ldots*) }
|
|
}
|
|
\end{lstlisting}
|
|
\begin{it}
|
|
Anche il listato \ref{lst:rdbrest-java} necessita di una breve spiegazione.
|
|
La classe astratta \textit{Readable}, vincolo sul primo parametro generico della classe,
|
|
è il padre di ogni classe ``entità'', mentre \textit{PrimaryKey<T>} è il padre
|
|
della classe contenente la chiave primaria di \textit{T}. Un'istanza della
|
|
classe figlia di \textit{PrimaryKey<T>} è contenuta come attributo nella
|
|
classe ``entità'' \textit{T}, che a sua volta estende \textit{Readable}.
|
|
\end{it}
|
|
\begin{en}
|
|
Even the listing \ref{lst:rdbrest-java} needs a brief explaination. The
|
|
abstract class \textit{Readable}, used as constraint for the class first generic
|
|
parameter, is the father of each ``entity'' class, while
|
|
\textit{PrimaryKey<T>} is the father of the class that contains the primary
|
|
key of \textit{T}. An instance the \textit{PrimaryKey<T>} child is embedded as
|
|
an attribute in the ``entity'' class \textit{T}, which itself extends \textit{Readable}.
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\def\crudrestjava-title{Interfaccia della classe \textit{CRUDRESTController}}
|
|
\end{it}
|
|
\begin{en}
|
|
\def\crudrestjava-title{Class interface of \textit{CRUDRESTController}}
|
|
\end{en}
|
|
\begin{lstlisting}[caption=\crudrestjava-title, label={crudrest-java}, language=Java]
|
|
/**
|
|
* A REST Controller readable and writable
|
|
* @param <T> The readable and writable entity class
|
|
*/
|
|
public abstract class CRUDRESTController<T extends CRUDable, U extends
|
|
PrimaryKey<T>> extends ReadableRESTController<T, U> {
|
|
|
|
/**
|
|
* A standard edit route body. Edits an entity and returns a JSON
|
|
* response, both on success and on error.
|
|
*
|
|
* @param filterOne map containing columns and relative values of the
|
|
* primary key of the entity to edit
|
|
* @param form request data containing the fields to edit
|
|
* @return JSON response, positive or negative
|
|
*/
|
|
protected Response edit(Map<String, Object> filterOne,
|
|
MultivaluedMap<String, String> form) { %*\ldots*) }
|
|
|
|
/**
|
|
* A standard edit route body. Edits an entity and returns a JSON
|
|
* response, both on success and on error.
|
|
*
|
|
* @param pKey the entity primary key
|
|
* @param form request data containing the fields to edit
|
|
* @return JSON response, positive or negative
|
|
*/
|
|
protected Response edit(PrimaryKey<T> pKey,
|
|
MultivaluedMap<String, String> form) { %*\ldots*) }
|
|
|
|
/**
|
|
* A standard delete route body. Deletes an entity and returns a JSON
|
|
* response, both on success and on error.
|
|
*
|
|
* @param pKey the entity primary key
|
|
* @return JSON response, positive or negative
|
|
*/
|
|
protected Response delete(PrimaryKey<T> pKey) { %*\ldots*) }
|
|
|
|
/**
|
|
* A standard delete route body. Deletes an entity and returns a JSON
|
|
* response, both on success and on error.
|
|
*
|
|
* @param filterOne map containing columns and relative values of the
|
|
* primary key of the entity to delete
|
|
* @return JSON response, positive or negative
|
|
*/
|
|
protected Response delete(Map<String, Object> filterOne) { %*\ldots*) }
|
|
|
|
/**
|
|
* A standard create route body. Creates an entity and returns a JSON
|
|
* response, both on success and on error.
|
|
*
|
|
* @param form request data containing the entity column values
|
|
* @return JSON response, positive or negative
|
|
*/
|
|
protected Response create(MultivaluedMap<String, String> form) { %*\ldots*) }
|
|
|
|
%*\ldots*)
|
|
}
|
|
\end{lstlisting}
|
|
|
|
\begin{it}
|
|
Si precisa che la classe \textit{CRUDable} è un estensione della classe
|
|
\textit{Readable} che contiene metodi per l'inizializzazione dell'oggetto
|
|
sulla base di dati in input, contenuti in \textit{MultivaluedMap<String,
|
|
String>}. Di conseguenza, le classi ``entità'' che estendono \textit{CRUDable}
|
|
possono essere usate per operazioni di scrittura, come quelle implementate
|
|
da \textit{CRUDRESTController}.
|
|
\end{it}
|
|
\begin{en}
|
|
The \textit{CRUDable} class extends \textit{Readable} and offers
|
|
some methods useful for object initialization based on input data given
|
|
as \textit{MultivaluedMap<String,String>}. Therefore, the ``entity''
|
|
classes that extend \textit{CRUDable} can be used for read-write operations,
|
|
e.g. the ones implemented in \textit{CRUDRESTController}.
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\def\crudutilsjava-title{Interfaccia della classe \textit{CRUDUtils}}
|
|
\end{it}
|
|
\begin{en}
|
|
\def\crudutilsjava-title{Class interface of \textit{CRUDUtils}}
|
|
\end{en}
|
|
\begin{lstlisting}[caption=\crudutilsjava-title, label={lst:crudutils-java}, language=Java]
|
|
/**
|
|
* Database access class. Access statically
|
|
*/
|
|
public abstract class CRUDUtils {
|
|
|
|
/**
|
|
* Interface containing a function able to generate an Hibernate Query
|
|
* object and execute it by getting a generic response given the
|
|
* session
|
|
*
|
|
* @param <T> the response type
|
|
*/
|
|
public interface HBMInteraction<T> {
|
|
T execute(Session s);
|
|
}
|
|
|
|
/**
|
|
* Interface containing a function able to generate an Hibernate Query
|
|
* object and execute it by getting a list of rows given the session
|
|
*/
|
|
public interface HBMQuery extends HBMInteraction<List<Object[]>> {
|
|
List<Object[]> execute(Session s);
|
|
}
|
|
|
|
/**
|
|
* Number of items on a single page. Used when pagination is requested
|
|
*/
|
|
public static final int ITEMSPERPAGE = %*\ldots*);
|
|
|
|
%*\ldots*)
|
|
|
|
private static final Logger log = %*\ldots*);
|
|
|
|
/**
|
|
* Save a writable entity on the database
|
|
*
|
|
* @param o the entity to save
|
|
* @param <T> type of the entity. Must be readable and writable
|
|
* @return boolean true = success, false = error
|
|
*/
|
|
public static <T extends CRUDable> boolean persist(final T o) { %*\ldots*) }
|
|
|
|
/**
|
|
* Delete a writable entity on the database
|
|
*
|
|
* @param toDelete the entity to delete
|
|
* @param <T> type of the entity. Must be readable and writable
|
|
* @return boolean true = success, false = error
|
|
*/
|
|
public static <T extends CRUDable> boolean delete(final T toDelete)
|
|
{ %*\ldots*) }
|
|
|
|
%*\ldots*)
|
|
|
|
/**
|
|
* Execute a query which returns data of a generic type
|
|
*
|
|
* @param query HBMInteraction implementation
|
|
* @param <T> The returning type
|
|
* @return the data
|
|
*/
|
|
public static <T> T executeHBMInteraction(HBMInteraction<T> query)
|
|
{ %*\ldots*) }
|
|
|
|
/**
|
|
* Get a list of entities
|
|
*
|
|
* @param tClass class of the entities
|
|
* @param restrictions map of names of fields and their values which
|
|
* must be equal in the fetched entities
|
|
* (null accepted if not used)
|
|
* @param criteria list of additional filters (Hibernate Criterion
|
|
* objects, null accepted if not used)
|
|
* @param <T> entity type. Must be readable
|
|
* @param o order of the entities (Hibernate Order, null accepted if
|
|
* not used)
|
|
* @param page the page number to fetch (starts at 1, null accepted if
|
|
* not used)
|
|
* @return the list of entities
|
|
*/
|
|
public static <T extends Readable> List<T> get(Class<T> tClass,
|
|
Map<String, Object> restrictions, List<Criterion> criteria,
|
|
Order[] o, Integer page) { %*\ldots*) }
|
|
|
|
/**
|
|
* Get a list of entities
|
|
*
|
|
* @param tClass class of the entities
|
|
* @param <T> entity type. Must be readable
|
|
* @return the list of entities
|
|
*/
|
|
public static <T extends Readable> List<T> get(Class<T> tClass) { %*\ldots*) }
|
|
|
|
|
|
/**
|
|
* Get a single entity
|
|
*
|
|
* @param tClass class of the entities
|
|
* @param restrictions map of names of fields and their values which
|
|
* must be equal in the fetched entities
|
|
* (null accepted if not used)
|
|
* @param <T> entity type. Must be readable
|
|
* @return the list of entities
|
|
*/
|
|
public static <T extends Readable> T getOne(Class<T> tClass,
|
|
Map<String, Object> restrictions) { %*\ldots*) }
|
|
|
|
/**
|
|
* Get a single entity
|
|
*
|
|
* @param tClass class of the entities
|
|
* @param pk the primary key object of the entity
|
|
* @param <T> entity type. Must be readable and contain a primary key
|
|
* object
|
|
* @return the list of entities
|
|
*/
|
|
public static <T extends Readable> T getOne(Class<T> tClass,
|
|
PrimaryKey<T> pk) { %*\ldots*) }
|
|
}
|
|
\end{lstlisting}
|
|
|
|
\begin{it}
|
|
Oltre a quanto mostrato, \textit{restaurant} contiene vari metodi utilità per
|
|
la gestione di file \texttt{.properties}, per la validazione dei dati in
|
|
input, per la registrazione della \textit{timestamp} di creazione o modifica
|
|
di un record, e altro ancora.
|
|
\end{it}
|
|
\begin{en}
|
|
Beside what shown, \textit{restaurant} includes many utility methods able to
|
|
manage \texttt{.properties} files, to validate input data, to register
|
|
creation and update \textit{timestamps}, and much more.
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\subsubsection{\textit{restaurant} -- lato client}
|
|
La parte client della libreria \textit{restaurant} è implementata con il
|
|
linguaggio \textit{TypeScript}, un'estensione di \textit{Javascript}
|
|
che aggiunge tipizzazione statica, i classici costrutti della programmazione
|
|
ad oggetti, nonchè il supporto alle generiche. Segue il listato dell'interfaccia della
|
|
classe \textit{RESTService}, la quale contiene metodi statici per comunicare
|
|
con il server asincronamente tramite istanze di classi ``entità'', cioè classi
|
|
figlie della classe astratta \textit{Table}.
|
|
\end{it}
|
|
\begin{en}
|
|
\subsubsection{\textit{restaurant} -- client side}
|
|
The client portion of the \textit{restaurant} library is implemented with the
|
|
\textit{TypeScript} progamming language, an extension of \textit{Javascript}
|
|
offering static typing, common OOP constructs and generics support. The
|
|
following listings describes the \textit{RESTService} class interface, which
|
|
contains some static methods useful to exchange data asyncronously with the
|
|
server in the form of instances of ``entity'' classes, inheriters of the
|
|
abstract class \textit{Table}.
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\def\restservicets-title{Interfaccia della classe \textit{RESTService}}
|
|
\end{it}
|
|
\begin{en}
|
|
\def\restservicets-title{Class interface of \textit{RESTService}}
|
|
\end{en}
|
|
\begin{lstlisting}[caption=\restservicets-title, label={lst:restservice-ts}, language=Java]
|
|
export class RESTService {
|
|
|
|
...
|
|
|
|
/**
|
|
* Read all the pages of an entity in order to save them for offline
|
|
* readings.
|
|
*
|
|
* @param {{ new(): T }} - class of the table to read
|
|
* @param {any} - key data for the search. Must not contain filters
|
|
* or a field with key '_page'
|
|
* @return {Promise<boolean>} boolean promise that resolves when the
|
|
* reading has been done, true if succesful,
|
|
* false if not
|
|
*/
|
|
public bulkRead<T extends Table>(type: TableStatic, restrictions?: any):
|
|
Promise<boolean> { ... }
|
|
|
|
/**
|
|
* Retrieves a list of entities. When online and requested without
|
|
* filters, the list is saved in the offline storage. When offline,
|
|
* the data from the offline storage is read and filtered accordingly.
|
|
*
|
|
* Request criteria regarding directly properties of the entity MUST
|
|
* have the following format:
|
|
*
|
|
* 'attr-' + name_of_property[.nested] [+ '||' + other_property] +
|
|
* ('-like' | '-eq' | '-flag' | '-gt' | '-lt' | '-gte' | '-lte')
|
|
*
|
|
* Multiple field names separed by '||' state that the search must be
|
|
* done on multiple fields with a logic OR.
|
|
*
|
|
* The different suffixes denote different logical criteria. Look up
|
|
* the documentation of the meetsCriteriaFilter*(...) methods in
|
|
* order to get detailed info on each one.
|
|
*
|
|
* @param {{ new(): T }} type - type of the table to read
|
|
* @param {number} page - number of the page starting at 1 (in offline
|
|
* mode, a 20 entities slice; in online mode,
|
|
* as defined by the server). -1 is for no
|
|
* pagination
|
|
* @param {any} restrictions - restrictions required by the server,
|
|
* and filters.
|
|
* @param {boolean} offline - whether to fetch (true) or not (false)
|
|
* offline entities to sync. Defaults to true
|
|
* @return {Promise<T[]>} - promise of the expanded list, unsuccesful
|
|
* when the storage readings are unsuccesful
|
|
*/
|
|
public read<T extends Table>(type: TableStatic, page: number,
|
|
restrictions?: any, addOffline?: boolean): Promise<T[]> { ... }
|
|
|
|
/**
|
|
* Asks to the server which entity instances of the ones
|
|
* saved in the offline storage exist and deletes the
|
|
* ones that do not exist on the server.
|
|
*
|
|
* @param {TableStatic} type - the entity type
|
|
* @return {Promise<void>} promise rejecting only if an error occurs
|
|
*/
|
|
private async existing(type: TableStatic): Promise<void> { ... }
|
|
|
|
/**
|
|
* Reads a single entity, even in the offline storage if offline.
|
|
*
|
|
* @param {{ new(): T }} type - class of the entity to read
|
|
* @param {any} keyData - the primary key fields and their values
|
|
* in a JS Object, plus the 'id' field of
|
|
* type string used in the end bit of the
|
|
* request path.
|
|
* @return {Promise<T>} - promise of the element, unsuccesful if
|
|
* not found.
|
|
*/
|
|
public readOne<T extends Table>(type: TableStatic | string,
|
|
keyData: any): Promise<T> { ... }
|
|
|
|
/**
|
|
* Updates an entity on the server or, if offline, saves it in the
|
|
* offline sync queue.
|
|
*
|
|
* @param {{ new(): T }} type - class of the entity to be saved
|
|
* @param {T} value - the entity to save
|
|
* @param {any} keyData - the primary key fields and their values
|
|
* in a JS Object, plus the 'id' field of
|
|
* type string used in the end bit of the
|
|
* request path.
|
|
* @return {Promise<T>} - promise of the saved element.
|
|
*/
|
|
public update<T extends Table>(type: TableStatic | string, value: T,
|
|
keyData: any): Promise<T> { ... }
|
|
|
|
/**
|
|
* Creates an entity on the server or, if offline, saves it in the
|
|
* offline sync queue.
|
|
*
|
|
* @param {{ new(): T }} type - class of the entity to be deleted
|
|
* @param {string} id - string used in the end bit of the request path.
|
|
* @param {any} keyData - the primary key fields and their values in
|
|
* a JS Object
|
|
* @return {Promise<T>} - promise of the element deleted
|
|
*/
|
|
public create<T extends Table>(type: TableStatic | string, value: T):
|
|
Promise<T> { ... }
|
|
|
|
/**
|
|
* Deletes an entity on the server or, if offline, marks it for
|
|
* deletion in the offline sync queue.
|
|
*
|
|
* @param {{ new(): T }} type - class of the entity to be saved
|
|
* @param {any} keyData - the primary key fields and their values in
|
|
* a JS Object, plus the 'id' field of type string
|
|
* that goes in the end bit of the request
|
|
* path
|
|
* @return {Promise<T>} - promise of the element created.
|
|
*/
|
|
public delete<T extends Table>(type: TableStatic | string, keyData: any):
|
|
Promise<T> { ... }
|
|
}
|
|
\end{lstlisting}
|
|
|
|
\begin{it}
|
|
\subsection{Stato del progetto}
|
|
\end{it}
|
|
\begin{en}
|
|
\subsection{Project status}
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\def\itgganttprg{Progettazione}
|
|
\def\itggantttf{Test funzioni}
|
|
\def\itgganttir{Impl. \textit{restaurant}}
|
|
\def\itgganttfunz{Impl. sezioni}
|
|
\def\itgganttim{Inv. di magazzino}
|
|
\def\itgganttcal{Agenda}
|
|
\def\itgganttsogg{Soggetti}
|
|
\def\itgganttco{Ordini cliente}
|
|
\def\itgganttrifr{Rininim. \textit{restaurant}}
|
|
\def\itggantttr{Test \textit{restaurant}}
|
|
\def\itgganttadtarch{Adattam. architettura}
|
|
\def\itgganttstr{Test}
|
|
\def\itgganttril{Finalizzazione}
|
|
\end{it}
|
|
\begin{en}
|
|
\def\itgganttprg{Planning}
|
|
\def\itggantttf{Sections testing}
|
|
\def\itgganttir{\textit{restaurant} impl.}
|
|
\def\itgganttfunz{Sections impl.}
|
|
\def\itgganttim{Warehouses}
|
|
\def\itgganttcal{Calendar}
|
|
\def\itgganttsogg{Customers and suppl.}
|
|
\def\itgganttco{Customers' orders}
|
|
\def\itgganttrifr{\textit{restaurant} improv.}
|
|
\def\itggantttr{\textit{restaurant} testing}
|
|
\def\itgganttadtarch{Architecture revising}
|
|
\def\itgganttstr{Testing}
|
|
\def\itgganttril{Finalisation}
|
|
\end{en}
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\resizebox{\ifdim\width>\linewidth\linewidth\else\width\fi}{!}{
|
|
\begin{ganttchart}{1}{49}
|
|
\gantttitle{2017}{28}
|
|
\gantttitle{2018}{21} \\
|
|
\gantttitle{6}{2}
|
|
\gantttitle{7}{4}
|
|
\gantttitle{8}{5}
|
|
\gantttitle{9}{4}
|
|
\gantttitle{10}{4}
|
|
\gantttitle{11}{5}
|
|
\gantttitle{12}{4}
|
|
\gantttitle{1}{5}
|
|
\gantttitle{2}{4}
|
|
\gantttitle{3}{4}
|
|
\gantttitle{4}{4}
|
|
\gantttitle{5}{4} \\
|
|
\gantttitlelist{25,...,52}{1}
|
|
\gantttitlelist{1,...,21}{1} \\
|
|
\ganttbar[name=prg]{\itgganttprg}{1}{1} \\
|
|
\ganttlinkedbar[name=ir]{\itgganttir}{2}{37} \\
|
|
\ganttgroup[name=funz]{\itgganttfunz}{2}{13} \\
|
|
\ganttbar{\itgganttim}{2}{4} \\
|
|
\ganttbar{\itgganttcal}{5}{6} \\
|
|
\ganttbar{\itgganttsogg}{7}{8} \\
|
|
\ganttbar{\itgganttco}{11}{13} \\
|
|
\ganttbar[name=tf]{\itggantttf}{14}{16} \\
|
|
\ganttlinkedgroup[name=tr]{\itggantttr}{19}{46} \\
|
|
\ganttbar{\itgganttadtarch}{19}{37} \\
|
|
\ganttbar[name=str]{\itgganttstr}{38}{46} \\
|
|
\ganttbar[name=ril]{\itgganttril}{47}{49}
|
|
\ganttlink{funz}{tf}
|
|
\ganttlink{prg}{funz}
|
|
\ganttlink{ir}{str}
|
|
\ganttlink{tr}{ril}
|
|
\end{ganttchart}
|
|
}
|
|
\begin{it}
|
|
\caption{Il diagramma di Gantt del progetto
|
|
\textit{InteGRa Mobile}}
|
|
\end{it}
|
|
\begin{en}
|
|
\caption{\textit{InteGRa Mobile} Gantt diagram}
|
|
\end{en}
|
|
\label{fig:ganttitgmob}
|
|
\end{figure}
|
|
|
|
\begin{it}
|
|
Il diagramma di Gantt in figura \ref{fig:ganttitgmob} non è stato rispettato:
|
|
il progetto non è stato completato entro la fine di maggio. Tuttavia, ci\`o che
|
|
è stato e doveva essere necessariamente completato \`e la parte pi\`u importante del progetto:
|
|
\textit{restaurant}, con il motore di sincronizzazione online/offline e
|
|
l'implementazione delle procedure generiche che permette di implementare velocemente nuove sezioni dell'applicazione.
|
|
\end{it}
|
|
\begin{en}
|
|
The Gantt diagram in figure \ref{fig:ganttitgmob} was not followed: the
|
|
project was not completed within the end of May. However, the most important
|
|
piece of software that did have to be working by the deadline was finished:
|
|
\textit{restaurant}, with the online/offline syncronization engine and the
|
|
interface and implementation of the procedures needed for generating in an easy
|
|
fashion new sections of the app.
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\subsection{Fasi del progetto}
|
|
|
|
Le fasi del progetto, di cui date di inizio e fine sono state specificate nel
|
|
diagramma in figura \ref{fig:ganttitgmob}, sono:
|
|
|
|
\begin{description}
|
|
|
|
\item[Progettazione] delineazione delle funzionalità da implementare
|
|
nell'applicazione e prime bozze dell'interfaccia utente;
|
|
|
|
\item[Implementazione \textit{restaurant}] implementazione della libreria su
|
|
cui si basano tutte le sezioni del programma. Vista l'importanza di questo
|
|
componente, gli sviluppi vengono continuati in parallelo con
|
|
l'implementazione delle sezioni;
|
|
|
|
\item[Implementazione sezioni] creazione di interfaccia e logica per le
|
|
funzionalit\'a previste, cio\'e:
|
|
\begin{itemize}
|
|
\item Magazzini;
|
|
\item Agenda;
|
|
\item Soggetti;
|
|
\item Ordini cliente;
|
|
\end{itemize}
|
|
|
|
\item[Test per le sezioni] collaudo degli algoritmi e della UI per
|
|
efficacia ed efficienza, nonch\'e eventuali correzioni;
|
|
|
|
\item[Rifinimento \textit{restaurant}] collaudo delle scelte
|
|
architetturali e algoritmi usati nella libreria e rifinimento di essi;
|
|
Fase divisa in:
|
|
\begin{description}
|
|
\item[Miglioramento architettura] analisi del protocollo per individuare
|
|
punti di debolezza e possibili ottimizzazioni;
|
|
\item[Test per \textit{restaurant}] messa alla prova dei cambiamenti fatti;
|
|
\end{description}
|
|
|
|
\item[Finalizzazione] task finali del progetto, tra cui branding, operazioni
|
|
pre-rilascio, e gestione di eventuali personalizzazioni richieste dai clienti.
|
|
|
|
\end{description}
|
|
\end{it}
|
|
\begin{en}
|
|
\subsection{Project phases}
|
|
|
|
The various project phases, by which start and end dates are shown on
|
|
the diagram in figure \ref{fig:ganttitgmob}, are described below.
|
|
|
|
\begin{description}
|
|
|
|
\item[Planning] features definition and first drafts of the user interface;
|
|
|
|
\item[\textit{restaurant} implementation] implementation of the library on
|
|
which all the sections are based. Given the importance of this component,
|
|
it is developed concurrently with the sections;
|
|
|
|
\item[Sections implementation] creation of user interface and business logic
|
|
for all the features planned, which are:
|
|
\begin{itemize}
|
|
\item Warehouses;
|
|
\item Calendar;
|
|
\item Customers and suppliers;
|
|
\item Customers' orders;
|
|
\end{itemize}
|
|
|
|
\item[Sections testing] trial of algorithms and UI to achieve effectiveness
|
|
and efficiency and possible adjustments;
|
|
|
|
\item[\textit{restaurant} improvement] trial of architectural choices and
|
|
algorithms used inside the library, with improvement of the last ones.
|
|
This phase is divided in:
|
|
\begin{description}
|
|
\item[Architecture revising] analisis of the protocol aimed to find weak
|
|
points and possible optimisations;
|
|
\item[\textit{restaurant} testing] trial of the changes implemented before;
|
|
\end{description}
|
|
|
|
\item[Finalisation] collection of final tasks, including branding, pre-release
|
|
operations and possible development of per-customer customizations.
|
|
|
|
\end{description}
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\section{Il progetto secondario: \textit{Guac Remote}}
|
|
|
|
Questo progetto \`e destinato ad un'importante azienda del territorio,
|
|
produttrice di macchine equilibratrici. Tale applicazione dovrebbe fungere da
|
|
client di desktop remoto (come \textit{TeamViewer}\footnote{TeamViewer:
|
|
\url{https://www.teamviewer.com/it}}) per il PC presente nel loro prodotto
|
|
di punta, un sistema di calibrazione delle ruote di autoveicoli funzionante
|
|
mediante telecamere. Il programma dovrebbe permettere all'operatore di tale
|
|
prodotto di interagire con il software presente nel macchinario, senza
|
|
scendere dal veicolo.
|
|
|
|
A causa di urgenza da parte del committente, lo sviluppo di questo progetto ha
|
|
interrotto sviluppi per \textit{InteGRa Mobile} fino alla fine del periodo di
|
|
alternanza estesa.
|
|
\end{it}
|
|
\begin{en}
|
|
\section{The side project: \textit{Guac Remote}}
|
|
|
|
This project is made for an important local company, which produces
|
|
wheel balancers. This application should work as a remote desktop client
|
|
(as \textit{TeamViewer}\footnote{TeamViewer: \url{https://www.teamviewer.com}})
|
|
for the PC mounted inside their main product, an automatic wheel balancer
|
|
that works with cameras. The program should allow the user to interact with the
|
|
wheel balancing software, without needing them to exit from the veichle.
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\subsection{Architettura software}
|
|
\end{it}
|
|
\begin{en}
|
|
\subsection{Software architecture}
|
|
\end{en}
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\resizebox{\ifdim\width>\linewidth\linewidth\else\width\fi}{!}{\input{diagrams/guacremote}}
|
|
\begin{it}
|
|
\caption{L'architettura di \textit{Guac Remote}}
|
|
\end{it}
|
|
\begin{en}
|
|
\caption{The architecture of \textit{Guac Remote} as a diagram}
|
|
\end{en}
|
|
\label{fig:argosarch}
|
|
\end{figure}
|
|
|
|
\begin{it}
|
|
\textit{Guac Remote} è basata su un'applicativo e libreria per la connessione
|
|
a computer remoto chiamato \textit{Apache Guacamole}\cite{guacamole:website}.
|
|
Tale software è costituito da due parti:\cite{guacdoc:arch}
|
|
\begin{description}
|
|
\item[\textit{guacamole-server} (o \textit{guacd})] un servizio scritto
|
|
in C che funge da adattatore tra il protocollo \textit{guacamole} e i
|
|
protocolli VNC, RDP o SSH, utilizzando questi ultimi per stabilire connessioni
|
|
con gli host remoti;
|
|
\item[\textit{guacamole-client}] una WebApplication scritta tramite
|
|
\textit{Java servlet} che fornisce un'interfaccia web per interagire con
|
|
\textit{guacamole-server} e connettersi ai PC remoti.
|
|
\end{description}
|
|
Data la natura open-source del progetto, sia \textit{guacamole-server} che
|
|
\textit{guacamole-client} possono essere usati come libreria per la
|
|
realizzazione di software derivati. In particolare, \textit{guacamole-client}
|
|
può essere scomposto nelle librerie \textit{guacamole-common-js}, che contiene
|
|
il codice Javascript per il client, e \textit{guacamole-common}, che fornisce
|
|
classi Java per la connessione con \textit{guacamole-server}\cite{guacdoc:api}.
|
|
|
|
In \textit{Guac Remote}, \textit{Apache Guacamole} è usato per fornire accesso
|
|
remoto al PC presente nel macchinario, che contiene l'applicativo per la
|
|
calibrazione, all'applicazione installata sul tablet. Nel dettaglio,
|
|
\textit{guacamole-common-js} è usato nell'applicazione \textit{mobile} (la quale
|
|
è basata su \textit{Apache Cordova}) per fornire
|
|
un'interfaccia touchscreen per interagire con l'host remoto, mentre
|
|
\textit{guacamole-common}, tramite una piccola Java Web Application, assieme a
|
|
\textit{guacamole-server} sono installati sul PC.
|
|
|
|
In aggiunta, tablet e PC possono comunicare informazioni aggiuntive tramite
|
|
una WebSocket creata al momento della connessione, necessaria per alcune
|
|
estensioni al protocollo richieste dal cliente.
|
|
\end{it}
|
|
\begin{en}
|
|
\textit{Guac Remote} is based on an application and library for remote desktop
|
|
connectivity named \textit{Apache Guacamole}\cite{guacamole:website}. This
|
|
software is a combination of two components:\cite{guacdoc:arch}
|
|
\begin{description}
|
|
\item[\textit{guacamole-server} (a.k.a. \textit{guacd})] a daemon written
|
|
in C which takes the role of an adapter between the \textit{guacamole}
|
|
protocol and the VNC, RDP and SSH protocols, using the last ones to connect
|
|
to the remote hosts;
|
|
\item[\textit{guacamole-client}] a Web Application written with \textit{Java
|
|
Servlets} that offers a web interface for interacting with
|
|
\end{description}
|
|
\textit{guacamole-server} and to connect with remote PCs.
|
|
Considering the open-source nature of the project, both \textit{guacamole-server}
|
|
and \textit{guacamole-client} can be used as a library for the implementation of
|
|
similar software. To be precise, \textit{guacamole-client} can be divided in the
|
|
libraries \textit{guacamole-common-js}, containing the client-side Javascript
|
|
code, and \textit{guacamole-common}, which contains Java classes for connecting
|
|
with \textit{guacamole-server}\cite{guacdoc:api}.
|
|
|
|
In \textit{Guac Remote}, \textit{Apache Guacamole} is used for granting remote
|
|
access on the PC inside the machine, containing the balancing software, to the
|
|
tablet containing the mobile app. In particular, \textit{guacamole-common-js} is
|
|
used in the mobile app (which is built with \textit{Apache Cordova}) in order to
|
|
make a touchscreen interface for the interacting with the remote host, while
|
|
\textit{guacamole-common}, bundled in a small Java Web Application, toghteter
|
|
with \textit{guacamole-server} are installed on the PC.
|
|
|
|
In addition, the tablet and the PC can share additional information through a
|
|
WebSocket created at the same time as the connection, which is needed by some
|
|
custom extensions commisioned by the customer.
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\subsection{Stato del progetto}
|
|
\end{it}
|
|
\begin{en}
|
|
\subsection{Project status}
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
\def\ganttargosprg{Incontro con il cliente}
|
|
\def\ganttargosprot{Realizzazione primo prototipo}
|
|
\def\ganttargosdemo{Prima demo al cliente}
|
|
\def\ganttargosstima{Stime orarie per sviluppi futuri}
|
|
\def\ganttargosimpl{Implementazione richieste \ldots}
|
|
\def\ganttargoszoom{Apertura tastiera e zoom \ldots}
|
|
\def\ganttargosscroll{Scroll a due dita}
|
|
\def\ganttargosconf{Interfaccia di configurazione}
|
|
\def\ganttargoskbd{Input tramite tastiera nativa \ldots}
|
|
\def\ganttargosdemodef{Demo al cliente}
|
|
\def\ganttargosagg{Implementazione richieste agg\ldots}
|
|
\def\ganttargoscon{Consegna}
|
|
\end{it}
|
|
\begin{en}
|
|
\def\ganttargosprg{Incontro con il cliente}
|
|
\def\ganttargosprot{Realizzazione primo prototipo}
|
|
\def\ganttargosdemo{Prima demo al cliente}
|
|
\def\ganttargosstima{Stime orarie per sviluppi futuri}
|
|
\def\ganttargosimpl{Implementazione richieste \ldots}
|
|
\def\ganttargoszoom{Apertura tastiera e zoom \ldots}
|
|
\def\ganttargosscroll{Scroll a due dita}
|
|
\def\ganttargosconf{Interfaccia di configurazione}
|
|
\def\ganttargoskbd{Input tramite tastiera nativa \ldots}
|
|
\def\ganttargosdemodef{Demo al cliente}
|
|
\def\ganttargosagg{Implementazione richieste agg\ldots}
|
|
\def\ganttargoscon{Consegna}
|
|
\end{en}
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\resizebox{\ifdim\width>\linewidth\linewidth\else\width\fi}{!}{
|
|
\begin{ganttchart}{1}{32}
|
|
\gantttitle{2018}{32} \\
|
|
\gantttitle{2}{6}
|
|
\gantttitle{3}{8}
|
|
\gantttitle{4}{8}
|
|
\gantttitle{5}{9}
|
|
\gantttitle{6}{1} \\
|
|
\gantttitlelist{7,...,22}{2} \\
|
|
\foreach \n in {7,...,22}{
|
|
\gantttitle{G}{1}
|
|
\gantttitle{V}{1}
|
|
} \\
|
|
\ganttbar[name=prg]{\ganttargosprg}{1}{1} \\
|
|
\ganttlinkedbar{\ganttargosprot}{2}{4} \\
|
|
\ganttlinkedbar{\ganttargosdemo}{5}{5} \\
|
|
\ganttlinkedbar{\ganttargosstima}{6}{6} \\
|
|
\ganttlinkedgroup[name=impl]{\ganttargosimpl}{8}{12} \\
|
|
\ganttbar{\ganttargoszoom}{8}{9} \\
|
|
\ganttbar{\ganttargoskbd}{10}{10} \\
|
|
\ganttbar{\ganttargosscroll}{11}{11} \\
|
|
\ganttbar{\ganttargosconf}{12}{12} \\
|
|
\ganttbar[name=demodef]{\ganttargosdemodef}{13}{13} \\
|
|
\ganttlinkedbar{\ganttargosagg}{14}{30} \\
|
|
\ganttlinkedbar{\ganttargoscon}{31}{32}
|
|
\ganttlink{impl}{demodef}
|
|
\end{ganttchart}
|
|
}
|
|
\begin{it}
|
|
\caption{Il diagramma di Gantt del progetto \textit{Guac Remote}}
|
|
\end{it}
|
|
\begin{en}
|
|
\caption{\textit{Guac Remote} diagram}
|
|
\end{en}
|
|
\label{fig:ganttargos}
|
|
\end{figure}
|
|
|
|
% TODO: cambiare quando diventa tesina vera e propria
|
|
\begin{it}
|
|
Questo progetto, al giorno 06/04, non ha ritardi. L'applicazione \'e stata
|
|
mostrata in demo il giorno 29/03, ed il cliente si ritiene soddisfatto del
|
|
lavoro fatto fino ad ora.
|
|
\end{it}
|
|
|
|
\begin{it}
|
|
\subsection{Fasi del progetto}
|
|
\end{it}
|
|
\begin{en}
|
|
\subsection{Project phases}
|
|
\end{en}
|
|
|
|
\begin{it}
|
|
Le fasi del progetto, di cui le date di inizio e di fine sono indicate nel
|
|
diagramma della figura \ref{fig:ganttargos}, sono:
|
|
|
|
\begin{description}
|
|
\item[Incontro con il cliente] primo scambio di informazioni per capire gli
|
|
obiettivi del progetto;
|
|
\item[Realizzazione primo prototipo] dimostrazione dell'efficacia del protocollo
|
|
\textit{guacamole} tramite un prototipo del prodotto;
|
|
\item[Prima dmo al cliente] demo del prototipo al cliente;
|
|
\item[Stime orarie per sviluppi futuri] delineazione della tabella di marcia per
|
|
gli sviluppi futuri;
|
|
\item[Implementazione richieste del cliente] sviluppo delle estensioni al
|
|
protocollo richieste. Nel dettaglio, esse sono:
|
|
\begin{description}
|
|
\item[Apertura tastiera e zoom al ``focus'' di un input] alla pressione di un
|
|
campo di testo, l'applicazione \textit{mobile} deve automaticamente ingrandire
|
|
l'area selezionata e mostrare una tastiera;
|
|
\item[Input tramite tastiera nativa Android o iOS] sostituzione della tastiera
|
|
su schermo di \textit{guacamole-common-js} con quella nativa;
|
|
\item[Scroll a due dita] supporto della gesture di scroll verticale a due dita;
|
|
\item[Interfaccia di configurazione] creazione di una piccola finestra di
|
|
configurazione, in cui inserire IP e porta del PC;
|
|
\end{description}
|
|
\item[Demo al cliente] dimostrazione degli sviluppi fatti al cliente e eventuale
|
|
definizione di richieste aggiuntive;
|
|
\item[Implementazione delle richieste aggiuntive del cliente]
|
|
\item[Consegna] operazioni finali del progetto, tra cui branding e compilazione
|
|
per rilascio.
|
|
\end{description}
|
|
\end{it}
|
|
\begin{en}
|
|
STUB
|
|
\end{en}
|
|
|
|
\newpage
|
|
|
|
\pagenumbering{gobble}
|
|
|
|
\listoffigures
|
|
\lstlistoflistings
|
|
\printbibliography
|
|
|
|
\end{document}
|