This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
laboratoare:laborator04 [2014/11/03 12:47] Andrei Roșu-Cojocaru [Activitate de Laborator] |
laboratoare:laborator04 [2014/11/17 20:54] (current) Andrei Roșu-Cojocaru [Soluții] |
||
|---|---|---|---|
| Line 4: | Line 4: | ||
| ===== Obiective ==== | ===== Obiective ==== | ||
| - | * înțelegerea mecanismului RMI | + | * înţelegerea mecanismului RMI pentru dezvoltarea unei aplicaţii distribuite, prin apelul la distanţă al metodelor unor obiecte rezidente pe server (într-o mașină virtuală Java diferită), funcţionalitate de care clientul este informat prin specificaţia în cadrul unei interfeţe care conține semnăturile metodelor ce pot fi invocate; |
| - | * distribuirea unei aplicații în funcționalități implementate în componente capabile să ruleze în mașini virtuale diferite, având un comportament vizibil "la distanță" | + | * cunoașterea capabilităților oferite de serviciul de nume RMI (rmiregistry) utilizat pentru identificarea obiectelor la distanță într-un mediu distribuit; |
| + | * descrierea unui serviciu disponibil la distanță prin definiții de metode în cadrul unei interfețe; | ||
| + | * specificarea unei politici de securitate atât pe server cât și pe client pentru a indica drepturile unui cod sursă rezident pe mașina virtuală Java respectivă / transmis prin transferul de comportament; | ||
| + | * precizarea configurațiilor de rulare necesare pentru lansarea în execuție a serverului și a clientului; | ||
| + | * proiectarea și configurarea serverului care implementează metodele unui obiect la distanță; | ||
| + | * proiectarea și configurarea clientului care invocă metodele unui obiect la distanță. | ||
| ===== Cuvinte Cheie ==== | ===== Cuvinte Cheie ==== | ||
| Line 13: | Line 18: | ||
| ===== Materiale Ajutătoare ====== | ===== Materiale Ajutătoare ====== | ||
| + | {{ :laboratoare:laborator04:aipi2014-lab04-slides.pdf }} | ||
| + | |||
| + | {{ :laboratoare:laborator04:aipi2014-lab04-slides-3pp.pdf }} | ||
| ===== RMI - aspecte generale ===== | ===== RMI - aspecte generale ===== | ||
| Line 106: | Line 114: | ||
| ==== Exemplu ==== | ==== Exemplu ==== | ||
| - | În cele ce urmează, implementarea unei aplicaţii distribuite folosind mecanismul RMI va fi ilustrată pe cazul particular al unui sistem informatic care gestionează locurile rezervate la un restaurant. | + | În cele ce urmează, implementarea unei aplicaţii distribuite folosind mecanismul RMI va fi ilustrată pe cazul particular al unui serviciu de rezervare a locurilor. |
| - | Restaurantul funcţionează după un anumit orar (diferit pentru fiecare dată calendaristică în parte) şi dispune de un număr de locuri. Aceste informaţii sunt disponibile în fişierul ''timetable.txt'' de pe sever, fiind încărcate la momentul lansării în execuţie a acestuia. În fişier se indică numărul de locuri disponibile, precum şi programul de funcţionare pentru fiecare zi în parte, respectând formatul ''ZZ LL AAAA O1 M1 O2 M2'' (unde ''O1:M1'' reprezintă momentul de timp de la care se doreşte să se facă rezervarea, iar ''O2:M2'' momentul de timp până la care aceasta este valabilă). | + | Rezervările pot fi realizate numai în cadrul unui program de funcționare (diferit pentru fiecare dată calendaristică în parte), serviciul fiind limitat la un anumit număr de locuri. Aceste informaţii sunt disponibile în fişierul ''timetable.txt'' din directorul ''input'' de pe sever, fiind încărcate la momentul lansării în execuţie a acestuia. În fişier se indică numărul de locuri disponibile, precum şi programul de funcţionare pentru fiecare zi în parte, respectând formatul ''ZZ LL AAAA O1 M1 O2 M2'' (unde ''O1:M1'' reprezintă momentul de timp de la care se doreşte să se facă rezervarea, iar ''O2:M2'' momentul de timp până la care aceasta este valabilă). |
| Aplicaţia va avea arhitectura client-server şi are definite semnăturile pentru metodele pe care va trebui să le implementaţi. | Aplicaţia va avea arhitectura client-server şi are definite semnăturile pentru metodele pe care va trebui să le implementaţi. | ||
| - | Pe server (''ReservationServer.java'') se vor reţine rezervările clienţilor fără a fi necesară asigurarea persistenţei (informaţiile sunt disponibile cât timp serverul rulează, pierzându-se ulterior). Tot aici vor fi implementate metodele din interfaţa pe care o cunoaşte şi clientul, fiind apelate în acest context. | + | Pe server (''ReservationImplementation.java'') se vor reţine rezervările clienţilor fără a fi necesară asigurarea persistenţei (informaţiile sunt disponibile cât timp serverul rulează, pierzându-se ulterior). Tot aici vor fi implementate metodele din interfaţa pe care o cunoaşte şi clientul, fiind apelate în acest context. |
| - | Fiecare client (''ReservationClient.java'') poate realiza o rezervare specificând o perioadă de timp preferată (orice durată) şi un număr de locuri. Dacă perioada de timp se încadrează în orarul specificat şi în intervalul respectiv există un număr de locuri libere corespunzător cererii făcute, atunci rezervarea este realizată şi locurile respective marcate ca ocupate. Este reţinut totodată şi identificatorul clientului care a realizat rezervarea, astfel încât tot acesta să aibă posibilitatea de a o anula, dacă situaţia o impune. Informaţiile cu privire la rezervările pe care clientul doreşte să le realizeze sunt preluate de la tastatură, respectând acelaşi format ca şi în fişier (dată calendaristică, intervalul orar pentru rezervarea respectivă, numărul de locuri solicitat), fără a fi necesară dezvoltarea unei interfeţe grafice. | + | Fiecare client (''Client.java'') poate realiza o rezervare specificând o perioadă de timp preferată (orice durată) şi un număr de locuri. Dacă perioada de timp se încadrează în orarul specificat şi în intervalul respectiv există un număr de locuri libere corespunzător cererii făcute, atunci rezervarea este realizată şi locurile respective marcate ca ocupate. Este reţinut totodată şi identificatorul clientului care a realizat rezervarea, astfel încât tot acesta să aibă posibilitatea de a o anula, dacă situaţia o impune. Informaţiile cu privire la rezervările pe care clientul doreşte să le realizeze sunt preluate de la tastatură, respectând acelaşi format ca şi în fişier (dată calendaristică, intervalul orar pentru rezervarea respectivă, numărul de locuri solicitat), fără a fi necesară dezvoltarea unei interfeţe grafice. |
| ==== Clase și Interfețe "la distanță" ==== | ==== Clase și Interfețe "la distanță" ==== | ||
| Line 205: | Line 213: | ||
| Obiectele locale sunt transmise prin valoare (este realizată o copie folosind mecanismul de serializare). Sunt copiate toate câmpurile care nu au precizat atributul ''static'' sau ''transient''. Orice modificare realizată în starea obiectului sunt reflectate doar în copie, dar nu şi în instanţa originală. Similar, schimbările asupra stării obiectului în instanţa originală nu vor fi reflectate în copie. | Obiectele locale sunt transmise prin valoare (este realizată o copie folosind mecanismul de serializare). Sunt copiate toate câmpurile care nu au precizat atributul ''static'' sau ''transient''. Orice modificare realizată în starea obiectului sunt reflectate doar în copie, dar nu şi în instanţa originală. Similar, schimbările asupra stării obiectului în instanţa originală nu vor fi reflectate în copie. | ||
| - | <file java ReservationServer.java> | + | <file java Server.java> |
| - | import java.rmi.RemoteException; | + | |
| import java.rmi.registry.LocateRegistry; | import java.rmi.registry.LocateRegistry; | ||
| import java.rmi.registry.Registry; | import java.rmi.registry.Registry; | ||
| import java.rmi.server.UnicastRemoteObject; | import java.rmi.server.UnicastRemoteObject; | ||
| - | import java.util.ArrayList; | ||
| - | public class ReservationServer implements Reservation { | + | public class Server { |
| + | |||
| + | public static void main (String[] args) { | ||
| | | ||
| - | public ReservationServer() { } | + | if (System.getSecurityManager() == null) |
| + | System.setSecurityManager(new SecurityManager()); | ||
| + | |||
| + | try { | ||
| + | String serviceName = "ReservationService"; | ||
| + | Reservation service = new ReservationImplementation(); | ||
| + | Reservation proxy = (Reservation)UnicastRemoteObject.exportObject(service, 0); | ||
| + | Registry registry = LocateRegistry.getRegistry(); | ||
| + | registry.rebind(serviceName, proxy); | ||
| + | } catch (Exception exception) { | ||
| + | System.out.println("An exception has occurred: "+exception.getMessage()); | ||
| + | if (Constants.DEBUG) | ||
| + | exception.printStackTrace(); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | } | ||
| + | </file> | ||
| + | |||
| + | <file java ReservationImplementation.java> | ||
| + | import java.rmi.RemoteException; | ||
| + | import java.util.ArrayList; | ||
| + | |||
| + | public class ReservationImplementation implements Reservation { | ||
| + | |||
| + | public ReservationServer() { | ||
| + | // ... | ||
| + | } | ||
| public ArrayList<Interval> getTimetable() throws RemoteException { | public ArrayList<Interval> getTimetable() throws RemoteException { | ||
| Line 230: | Line 265: | ||
| public boolean cancelReservation(int customerId, Interval interval) throws RemoteException { | public boolean cancelReservation(int customerId, Interval interval) throws RemoteException { | ||
| // ... | // ... | ||
| - | } | ||
| - | |||
| - | public static void main (String[] args) { | ||
| - | if (System.getSecurityManager() == null) { | ||
| - | System.setSecurityManager(new SecurityManager()); | ||
| - | } | ||
| - | try { | ||
| - | String serviceName = "ReservationService"; | ||
| - | Reservation service = new ReservationServer(); | ||
| - | Reservation proxy = | ||
| - | (Reservation)UnicastRemoteObject.exportObject(service, 0); | ||
| - | Registry registry = LocateRegistry.getRegistry(); | ||
| - | registry.rebind(serviceName, proxy); | ||
| - | } catch (Exception exception) { } | ||
| } | } | ||
| - | } | + | } |
| </file> | </file> | ||
| Line 277: | Line 298: | ||
| <code bash> | <code bash> | ||
| - | $ javac –cp reservation.jar ReservationServer.java | + | $ javac –cp libs/reservation.jar Server.java |
| </code> | </code> | ||
| Line 289: | Line 310: | ||
| </code> | </code> | ||
| * Unix <code bash> | * Unix <code bash> | ||
| - | # rmiregistry [port] –J-Djava.rmi.server.useCodebaseOnly=false & | + | $ rmiregistry [port] –J-Djava.rmi.server.useCodebaseOnly=false & |
| </code> | </code> | ||
| * specificarea unei politici de securitate, într-un fişier denumit ''policy[.txt]'', codul sursă obţinând permisiunile de care are nevoie pentru a putea rula: <file policy> | * specificarea unei politici de securitate, într-un fişier denumit ''policy[.txt]'', codul sursă obţinând permisiunile de care are nevoie pentru a putea rula: <file policy> | ||
| - | grant codebase "file:///<cale_absoluta>\\ReservationServer\\-" { | + | grant codebase "file://<cale_absoluta>/ReservationServer/-" { |
| permission java.security.AllPermission; | permission java.security.AllPermission; | ||
| }; | }; | ||
| Line 301: | Line 322: | ||
| Lansarea în execuţie a serverului se face prin comanda: | Lansarea în execuţie a serverului se face prin comanda: | ||
| * Windows <code bash> | * Windows <code bash> | ||
| - | > java -cp .;reservation.jar | + | > java -cp .;libs/reservation.jar |
| - | -Djava.rmi.server.codebase=file:///<cale_absoluta>\reservation.jar | + | -Djava.rmi.server.codebase=file://<cale_absoluta>/ReservationServer/libs/reservation.jar |
| -Djava.rmi.server.hostname=localhost | -Djava.rmi.server.hostname=localhost | ||
| - | -Djava.security.policy=policy | + | -Djava.security.policy=configuration/policy |
| - | ReservationServer | + | Server |
| </code> | </code> | ||
| * Linux <code bash> | * Linux <code bash> | ||
| - | > java -cp .:reservation.jar | + | > java -cp .:libs/reservation.jar |
| - | -Djava.rmi.server.codebase=file:///<cale_absoluta>\reservation.jar | + | -Djava.rmi.server.codebase=file://<cale_absoluta>/ReservationServer/libs/reservation.jar |
| -Djava.rmi.server.hostname=localhost | -Djava.rmi.server.hostname=localhost | ||
| - | -Djava.security.policy=policy | + | -Djava.security.policy=configuration/policy |
| - | ReservationServer | + | Server |
| </code> | </code> | ||
| Line 331: | Line 352: | ||
| - Se va crea un obiect de tip ''Interval'' (eventual din parametrii specificaţi în linia de comandă) şi se vor **apela metodele la distanţă**, afişându-se rezultatul. | - Se va crea un obiect de tip ''Interval'' (eventual din parametrii specificaţi în linia de comandă) şi se vor **apela metodele la distanţă**, afişându-se rezultatul. | ||
| - | <file java ReservationClient.java> | + | <file java Client.java> |
| import java.rmi.registry.LocateRegistry; | import java.rmi.registry.LocateRegistry; | ||
| import java.rmi.registry.Registry; | import java.rmi.registry.Registry; | ||
| - | public class ReservationClient { | + | public class Client { |
| - | public static void main(String[] args) { | + | public static void main(String[] args) { |
| - | if (System.getSecurityManager() == null) { | + | |
| + | if (System.getSecurityManager() == null) | ||
| System.setSecurityManager(new SecurityManager()); | System.setSecurityManager(new SecurityManager()); | ||
| - | } | ||
| try { | try { | ||
| Line 352: | Line 373: | ||
| if (reservation.makeReservation(customerId,interval,numberOfSeats)) { | if (reservation.makeReservation(customerId,interval,numberOfSeats)) { | ||
| - | System.out.println("succes"); | + | System.out.println("The reservation has been made successfully"); |
| } else { | } else { | ||
| - | System.out.println("insucces"); | + | System.out.println("The reservation has not been made successfully"); |
| } | } | ||
| - | } catch (Exception exception) { } | + | } catch (Exception exception) { |
| + | System.out.println("An exception has occurred: "+exception.getMessage()); | ||
| + | if (Constants.DEBUG) | ||
| + | exception.printStackTrace(); | ||
| + | } | ||
| } | } | ||
| } | } | ||
| Line 364: | Line 389: | ||
| <code bash> | <code bash> | ||
| - | > javac –cp reservation.jar ReservationClient.java | + | $ javac –cp libs/reservation.jar Client.java |
| </code> | </code> | ||
| Line 371: | Line 396: | ||
| * lansarea în execuţie a aplicaţiei server ''ReservationServer''; | * lansarea în execuţie a aplicaţiei server ''ReservationServer''; | ||
| * specificarea unei politici de securitate, într-un fişier numit ''policy[.txt]'', codul sursă obţinând permisiunile de care are nevoie pentru a putea rula: <file policy> | * specificarea unei politici de securitate, într-un fişier numit ''policy[.txt]'', codul sursă obţinând permisiunile de care are nevoie pentru a putea rula: <file policy> | ||
| - | grant codebase "file:///<cale_absoluta>\\ReservationClient\\-" { | + | grant codebase "file://<cale_absoluta>/ReservationClient/-" { |
| permission java.security.AllPermission; | permission java.security.AllPermission; | ||
| }; | }; | ||
| Line 378: | Line 403: | ||
| Lansarea în execuţie a serverului se face prin comanda: | Lansarea în execuţie a serverului se face prin comanda: | ||
| * Windows <code bash> | * Windows <code bash> | ||
| - | > java -cp .;reservation.jar | + | > java -cp .;libs/reservation.jar |
| - | -Djava.rmi.server.codebase=file:///<cale_absoluta>\ | + | -Djava.rmi.server.codebase=file://<cale_absoluta>/ReservationClient/libs/reservation.jar |
| - | -Djava.security.policy=policy | + | -Djava.security.policy=configuration/policy |
| - | ReservationClient <adresa> | + | Client <rmiregistry_IP_address> |
| </code> | </code> | ||
| * Unix <code bash> | * Unix <code bash> | ||
| - | > java -cp .:reservation.jar | + | > java -cp .:libs/reservation.jar |
| - | -Djava.rmi.server.codebase=file:///<cale_absoluta>\ | + | -Djava.rmi.server.codebase=file://<cale_absoluta>/ReservationClient/libs/reservation.jar |
| - | -Djava.security.policy=policy | + | -Djava.security.policy=configuration/policy |
| - | ReservationClient <adresa> | + | Client <rmiregistry_IP_address> |
| </code> | </code> | ||
| Line 396: | Line 421: | ||
| Proprietatea ''codebase'' din fişierul ce conţine politica de securitate (atât pentru server cât şi pentru client) trebuie să ofere permisiuni maxime pentru toate clasele aflate în structura de directoare a serverului, respectiv a clientului. | Proprietatea ''codebase'' din fişierul ce conţine politica de securitate (atât pentru server cât şi pentru client) trebuie să ofere permisiuni maxime pentru toate clasele aflate în structura de directoare a serverului, respectiv a clientului. | ||
| - | Configuraţiile de rulare implică specificarea proprietăţilor Java ''java.rmi.server.codebase'' (ce indică spre arhiva .jar ce conţine clasele care trebuie încărcate – în cazul serverului, respectiv directorul în care clientul îşi defineşte clasele – în cazul serverului), ''java.rmi.server.hostname'' pentru server şi ''java.security.policy'' atât pentru server cât şi pentru client. | + | Configuraţiile de rulare implică specificarea proprietăţilor Java ''java.rmi.server.codebase'' (ce indică spre arhiva .jar ce conţine clasele care trebuie încărcate – în cazul serverului, respectiv directorul în care clientul îşi defineşte clasele – în cazul clientului), ''java.rmi.server.hostname'' pentru server şi ''java.security.policy'' atât pentru server cât şi pentru client. |
| - | + | ||
| + | {{ :laboratoare:laborator04:netbeans01.png?nolink&300 }} | ||
| + | |||
| + | {{ :laboratoare:laborator04:netbeans02.png?nolink&700 }} | ||
| + | |||
| + | {{ :laboratoare:laborator04:netbeans03.png?nolink&300 }} | ||
| + | |||
| + | {{ :laboratoare:laborator04:netbeans04.png?nolink&700 }} | ||
| Modificarea configuraţiei de rulare în NetBeans 8.0.1 | Modificarea configuraţiei de rulare în NetBeans 8.0.1 | ||
| + | |||
| + | {{ :laboratoare:laborator04:eclipse01.png?nolink&300 }} | ||
| + | |||
| + | {{ :laboratoare:laborator04:eclipse02.png?nolink&700 }} | ||
| + | |||
| + | {{ :laboratoare:laborator04:eclipse03.png?nolink&700 }} | ||
| + | |||
| + | {{ :laboratoare:laborator04:eclipse04.png?nolink&700 }} | ||
| + | |||
| + | {{ :laboratoare:laborator04:eclipse05.png?nolink&700 }} | ||
| + | |||
| + | {{ :laboratoare:laborator04:eclipse06.png?nolink&700 }} | ||
| Modificarea configuraţiei de rulare în Eclipse 4.4.1 (Luna SR1) | Modificarea configuraţiei de rulare în Eclipse 4.4.1 (Luna SR1) | ||
| + | |||
| + | Nu este neapărat necesar ca proprietățile să fie specificate în cadrul configurațiilor de rulare, acestea pot fi precizate și în codul sursă (înainte de a se implementa politica de securitate): | ||
| + | |||
| + | <code java> | ||
| + | System.setProperty("java.rmi.server.codebase", "file://..."); | ||
| + | System.setProperty("java.security.policy", "configuration/policy"); | ||
| + | </code> | ||
| ===== Activitate de Laborator ===== | ===== Activitate de Laborator ===== | ||
| Line 408: | Line 460: | ||
| {{ :laboratoare:laborator04:aipi2014-lab04-remoteinterfaces.zip }} | {{ :laboratoare:laborator04:aipi2014-lab04-remoteinterfaces.zip }} | ||
| + | {{ :laboratoare:laborator04:aipi2014-lab04-eclipse.zip }} | ||
| + | {{ :laboratoare:laborator04:aipi2014-lab04-netbeans.zip }} | ||
| **1.** [**0 puncte**] Să se pornească registrul de nume ''rmiregistry'' prin apelarea scripturilor ''startRmiRegistry [.bat|.sh]''. | **1.** [**0 puncte**] Să se pornească registrul de nume ''rmiregistry'' prin apelarea scripturilor ''startRmiRegistry [.bat|.sh]''. | ||
| Line 414: | Line 468: | ||
| În cazul când calea către directorul bin al SDK-ului Java nu este precizată în variabila de mediu ''PATH'', acest script nu va fi executat cu succes. | În cazul când calea către directorul bin al SDK-ului Java nu este precizată în variabila de mediu ''PATH'', acest script nu va fi executat cu succes. | ||
| - | Precizarea căii către directorul ''bin'' al SDK-ului Java în variabila de mediu ''PATH'' se realizează prin instrucţiunile: <code bash> | + | Precizarea căii către directorul ''bin'' al SDK-ului Java în variabila de mediu ''PATH'' se realizează astfel: |
| - | SET PATH=%PATH%;C:\Program Files\Java\jdk1.8.0_25\bin | + | * Linux <code bash> |
| export PATH=${PATH}:/usr/lib/jvm/default-java/bin | export PATH=${PATH}:/usr/lib/jvm/default-java/bin | ||
| </code> | </code> | ||
| + | * Windows Computer Properties → Control Panel Home/Advanced System Properties → System Properties/Advanced/Environment Variables → System Variables / Path / Edit<code bash> | ||
| + | SET PATH=%PATH%;C:\Program Files\Java\jdk1.8.0_25\bin | ||
| + | </code>\\ {{ :laboratoare:laborator04:windows7_01.png?nolink }}\\ {{ :laboratoare:laborator04:windows7_02.png?nolink&400 }}\\ {{ :laboratoare:laborator04:windows7_03.png?nolink&400 }}\\ {{ :laboratoare:laborator04:windows7_04.png?nolink&400 }} | ||
| - | <note tip>Verificaţi că procesul ''rmiregistry'' rulează înainte de a porni serverul.</note> | + | <note tip>Verificaţi că procesul ''rmiregistry'' rulează înainte de a porni serverul. |
| + | * Linux <code bash> | ||
| + | aipi2014@ubuntu:~$ ps -a | ||
| + | </code> | ||
| + | * Windows - procesul apare în lista Task Manager | ||
| + | </note> | ||
| <note important>Dacă aveţi mai multe versiuni de Java instalate, verificaţi faptul că serviciul de nume ''rmiregistry'' corespunde versiunii cu care dezvoltaţi aplicaţiile, altfel conexiunea la serviciul de nume va eşua.</note> | <note important>Dacă aveţi mai multe versiuni de Java instalate, verificaţi faptul că serviciul de nume ''rmiregistry'' corespunde versiunii cu care dezvoltaţi aplicaţiile, altfel conexiunea la serviciul de nume va eşua.</note> | ||
| - | **2.** [**0 puncte**] Să se modifice căile absolute din fişierele ''policy'', respectiv din configuraţiile de rulare (Eclipse / Netbeans) pentru rularea serverului, respectiv a clientului. | + | **2.** [**0 puncte**] a) Să se recreeze arhiva .jar conținând definițiile de clase, prin compilarea surselor din ''aipi2014-lab04-remoteinterfaces.zip'' și împachetarea lor. |
| + | |||
| + | <code bash> | ||
| + | aipi2014@ubuntu:~$ javac ro/pub/cs/aipi/lab04/reservation/*.java | ||
| + | aipi2014@ubuntu:~$ jar cvf reservation.jar ro/pub/cs/aipi/lab04/reservation/*.class | ||
| + | </code> | ||
| + | |||
| + | Să se suprascrie fișierul ''reservation.jar'' obținut în proiectele corespunzătoare serverului (''ReservationServer'') și clientului (''ReservationClient''), în directorul ''lib/''. Se asigură astfel că sursele încărcate au fost compilate folosind aceeași versiune de Java ca și serverul / clientul, care vor folosi definițiile de clase respective. | ||
| + | |||
| + | b) Să se modifice căile absolute din fişierul ''policy'' corespunzător serverului, respectiv din configuraţiile de rulare (Eclipse / Netbeans) pentru rularea serverului și a clientului. | ||
| **3.** [**10 puncte**] Să se încarce orarul de funcţionare al restaurantului în constructorul clasei ''ReservationServer'' cu datele conţinute de fişierul ''timetable.txt''. | **3.** [**10 puncte**] Să se încarce orarul de funcţionare al restaurantului în constructorul clasei ''ReservationServer'' cu datele conţinute de fişierul ''timetable.txt''. | ||
| Se va parsa conţinutul fişierului ''timetable.txt'' care pe prima linie conţine capacitatea (numărul de locuri) încărcată în variabila ''numberOfSeats'' iar pe următoarele linii programul pentru fiecare zi calendaristică exprimat sub forma ''ZZ LL AAAA O1 M1 O2 M2'', acesta fiind încărcat în obiectul ''timetable''. | Se va parsa conţinutul fişierului ''timetable.txt'' care pe prima linie conţine capacitatea (numărul de locuri) încărcată în variabila ''numberOfSeats'' iar pe următoarele linii programul pentru fiecare zi calendaristică exprimat sub forma ''ZZ LL AAAA O1 M1 O2 M2'', acesta fiind încărcat în obiectul ''timetable''. | ||
| - | |||
| - | Să se implementeze metoda ''getTimetable()'' a clasei ''ReservationServer'', care întoarce conţinutul obiectului ''timetable''. | ||
| <note tip>În constructorul clasei ''GregorianCalendar'', lunile sunt numerotate începând cu valoarea 0.</note> | <note tip>În constructorul clasei ''GregorianCalendar'', lunile sunt numerotate începând cu valoarea 0.</note> | ||
| Line 451: | Line 520: | ||
| result = numberOfSeats; | result = numberOfSeats; | ||
| // check if interval is in timetable | // check if interval is in timetable | ||
| - | for-each(currentInterval ∈ timetable) | + | for-all(currentInterval ∈ timetable) |
| if (interval.getStartingTime() < currentInterval.getStartingTime() || interval.getEndingTime() > currentInterval.getEndingTime()) | if (interval.getStartingTime() < currentInterval.getStartingTime() || interval.getEndingTime() > currentInterval.getEndingTime()) | ||
| return -1; | return -1; | ||
| Line 467: | Line 536: | ||
| } | } | ||
| - | if (intervalIntersections ≠ ∅) { | + | if (intersectionPoints ≠ ∅) { |
| // sort intersection points | // sort intersection points | ||
| sort(intersectionPoints); | sort(intersectionPoints); | ||
| Line 513: | Line 582: | ||
| <note>Acest exerciţiu nu va fi punctat decât în cadrul laboratorului.</note> | <note>Acest exerciţiu nu va fi punctat decât în cadrul laboratorului.</note> | ||
| - | **9.** [**20 puncte**] Să se implementeze metoda ''getReservation(int clientId)'' ca fiind apelabilă la distanţă, aceasta întorcând lista cu intervalele în care clientul respectiv are făcute rezervări, precum şi numărul de locuri rezervate în fiecare dintre cazuri. | + | **9.** [**20 puncte**] Să se implementeze metoda ''ArrayList<ReservationInformation> getReservation(int clientId)'' ca fiind apelabilă la distanţă, aceasta întorcând lista cu intervalele în care clientul respectiv are făcute rezervări, precum şi numărul de locuri rezervate în fiecare dintre cazuri. |
| + | |||
| + | <note important>Clasa ''ReservationInformation'', care conține informații despre rezervările utilizatorului, va trebui să fie serializabilă.</note> | ||
| ===== Resurse ====== | ===== Resurse ====== | ||
| - | [[http://docs.oracle.com/javase/tutorial/rmi/index.html|The Java Tutorials - Trail: RMI]] | + | [[http://docs.oracle.com/javase/tutorial/rmi/index.html|The Java Tutorials - Trail: RMI]]\\ |
| + | [[http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136424.html|Remote Method Invocation Home]]\\ | ||
| + | [[http://www.genady.net/rmi/v20/downloads.html|RMI Plug-in for Eclipse v2.0]] | ||
| ===== Soluții ===== | ===== Soluții ===== | ||
| - | disponibile pe 13 noiembrie | + | [[https://github.com/aipi2014/Laborator04/tree/master/Eclipse/|Proiect Eclipse]]\\ |
| + | [[https://github.com/aipi2014/Laborator04/tree/master/NetBeans/|Proiect NetBeans]] | ||