Upload
oswald-austin
View
214
Download
0
Embed Size (px)
Citation preview
PresentationPresentationCDnowCDnow
Project adviser:Project adviser:
Prof. Michel BuffaProf. Michel Buffa
Project members:Project members:
Alex, Sébastien, Nicolas,Alex, Sébastien, Nicolas,
Adriaan, Jörn, ThomasAdriaan, Jörn, Thomas
AgendaAgenda
IntroductionIntroduction
DemoDemo
Project cut in 2 partsProject cut in 2 parts1. Business logic & Presentation layer1. Business logic & Presentation layer
based on JSP/Servlets & XML/XSLbased on JSP/Servlets & XML/XSL
German Teams WorkGerman Teams Work
2. Backend Work2. Backend Workall Database Managementall Database Management
French Teams WorkFrench Teams Work
OutlookOutlook
What is the project aboutWhat is the project about
Testing new technologiesTesting new technologies
Make a CDnow.com cloneMake a CDnow.com clone
Implementing possibility to download MP3Implementing possibility to download MP3´s via this page´s via this page
Thinking of extensionsThinking of extensions
FreeDBDBWebsite
InBrowser
JSP + Web server
Structure of Project „CD-Now“Structure of Project „CD-Now“
Pics +MP3
Form Request
XML + XSLT
Shopping Chart
Cookies
Load on Demand
Used if enabled
Once imported
Location InfoJDBC
Database Logic
Stored whithin the Session
Web Session + interactive Logic
German Side French Side
AgendaAgenda
IntroductionIntroduction
DemoDemo
Project cut in 2 partsProject cut in 2 parts1. Business logic & Presentation layer1. Business logic & Presentation layer
based on JSP/Servlets & XML/XSLbased on JSP/Servlets & XML/XSL
German Teams WorkGerman Teams Work
2. Backend Work2. Backend Workall Database Managementall Database Management
French Teams WorkFrench Teams Work
OutlookOutlook
DemoDemo
www.cdnow.comwww.cdnow.com
CDNow-CloneCDNow-Clone
AgendaAgenda
IntroductionIntroduction
DemoDemo
Project cut in 2 partsProject cut in 2 parts1. Business logic & Presentation layer1. Business logic & Presentation layer
based on JSP/Servlets & XML/XSLbased on JSP/Servlets & XML/XSL
German Teams WorkGerman Teams Work
2. Backend Work2. Backend Workall Database Managementall Database Management
French Teams WorkFrench Teams Work
OutlookOutlook
JSPJSP
JSPJSP
About JSPAbout JSPKey feature for the projectKey feature for the projectJava BeansJava BeansHow did we use JSP for our project?How did we use JSP for our project?Parameter handlingParameter handlingWhy did we only use one JSP Page?Why did we only use one JSP Page?Session managementSession management
About JSP (Example-code)About JSP (Example-code)<html><html><head><head><title><title> JSP Example 2JSP Example 2</title></title></head></head><body><body><h1>JSP Example 2 at <%= new java.util.Date() %> o‘clock</h1><h1>JSP Example 2 at <%= new java.util.Date() %> o‘clock</h1><% <%
StringString sn1;sn1;StringString sn2;sn2;int n1,n2;int n1,n2;sn1 = request.getParameter("n1");sn1 = request.getParameter("n1");sn2 = request.getParameter("n2");sn2 = request.getParameter("n2");n1 = Integer.parseInt(sn1);n1 = Integer.parseInt(sn1);n2 = Integer.parseInt(sn2);n2 = Integer.parseInt(sn2);out.println("The numbers were " + sn1 + " and " + sn2);out.println("The numbers were " + sn1 + " and " + sn2);out.println("<br>");out.println("<br>");out.println("The sum is " + (n1+n2));out.println("The sum is " + (n1+n2));
%>%></body> </body> </html></html>
Key feature for the projectKey feature for the projectIntegration with the Java platformIntegration with the Java platform JSP is a key component of the Java JSP is a key component of the Java platform platform JAVA is the native scripting languageJAVA is the native scripting languageWe have all the advantages of JAVA:We have all the advantages of JAVA: PortablePortable PlatformindependantPlatformindependant JDBC for communication with a wide variety JDBC for communication with a wide variety
of databasesof databases ......
Java Beans and JSPJava Beans and JSP
Small finished program components Small finished program components
Re-usableRe-usable
Contains the business and data logic for Contains the business and data logic for an applicationan application
Through JSP easily integrated in a web Through JSP easily integrated in a web applicationapplication
How did we use JSP for our How did we use JSP for our project?project?
We only have one JSP-page:We only have one JSP-page:
<jsp:useBean id="pg" class="cdnow.Core"/><jsp:useBean id="pg" class="cdnow.Core"/><jsp:useBean id="param" <jsp:useBean id="param"
class="cdnow.Parameter"/>class="cdnow.Parameter"/><jsp:setProperty name="param" property="*" /><jsp:setProperty name="param" property="*" /><%=<%=
pg.generatePage(param)pg.generatePage(param)%>%>
Parameter handlingParameter handling
Example-request:Example-request:http://miageprojet.unice.fr:8085/cdnow/index.jsp?http://miageprojet.unice.fr:8085/cdnow/index.jsp?
op=search&opt=artist&artist=jacksonop=search&opt=artist&artist=jacksonJAVABean ParameterJAVABean Parameterpublic class Parameter {public class Parameter {
private String op;private String op;private String opt;private String opt;
......public void setOp (String x) {public void setOp (String x) {
op = x;op = x;}}......
}}
Why did we only use one JSP Why did we only use one JSP Page?Page?
Just one service pointJust one service point
Easy to maintainEasy to maintain
All other code is pure javaAll other code is pure java
Easier to testEasier to test
Can be developed using any java Can be developed using any java programming environment (like e.g. programming environment (like e.g. JBuilder)JBuilder)
Session managementSession management
JSP-server automatically creates JSP-server automatically creates important objects (implicit objects)important objects (implicit objects)
We outreach the implicit object We outreach the implicit object sessionsession to to the bean the bean CoreCore
<% <% pg.setSession(session)pg.setSession(session) %> %>
Object Object sessionsession shares information for one shares information for one user across multiple pages while visiting user across multiple pages while visiting the web sitethe web site
XML & XSLXML & XSL
XML & XSLXML & XSL
Why we used XMLWhy we used XML
What is XML ?What is XML ?
What is XSL ?What is XSL ?
How we used it?How we used it?
What is XMLWhat is XML
XML (EXML (Exxtensible tensible MMarkup arkup LLanguage)anguage)User extensible markup languageUser extensible markup language Domain-specific markup languagesDomain-specific markup languages
Seperation of contents from presentationSeperation of contents from presentationHuman-readableHuman-readableWell-formedWell-formedXML-Tree-structure / ValidationXML-Tree-structure / Validation Easy to access / rearrange Easy to access / rearrange SchemasSchemas DTD (Document Type Definition)DTD (Document Type Definition)
XML-Tree-ExampleXML-Tree-Example
XML-FileXML-File
<document><document>
<publication><publication>
<author><author>
<firstname>Peter</firstname><firstname>Peter</firstname>
<lastname>Mustermann</lastname><lastname>Mustermann</lastname>
<adress><adress>
<street>L 15,16</street><street>L 15,16</street>
<postalcode>68161</postalcode><postalcode>68161</postalcode>
<city>Mannheim</city><city>Mannheim</city>
</adress></adress>
</author></author>
<abstract>… </abstract><abstract>… </abstract>
</publication></publication>
</document></document>
XML-TreeXML-Tree
document
publication
authorabstract
firstname lastname adress
street postalcodecity
Album-Search (XML)Album-Search (XML)<?xml version="1.0" encoding="ISO-8859-1"?><?xml version="1.0" encoding="ISO-8859-1"?><?xml-stylesheet type="text/xsl" href="cd-now-stylesheet.xsl"?><?xml-stylesheet type="text/xsl" href="cd-now-stylesheet.xsl"?>
<album_search parameter="d=a&f=f&s=d&“ loggedIn=<album_search parameter="d=a&f=f&s=d&“ loggedIn=""Yes“>Yes“><result><result>
<album><album><title>Titel of album 1</title><title>Titel of album 1</title><interpret>Interpret of album 1</interpret><interpret>Interpret of album 1</interpret><genre>Genre of album 1</genre><genre>Genre of album 1</genre>
</album></album><album><album>
<title>Titel of album 2</title><title>Titel of album 2</title><interpret>Interpret of album 2</interpret><interpret>Interpret of album 2</interpret><genre>Genre of album 2</genre><genre>Genre of album 2</genre>
</album></album></result></result>
</album_search></album_search>
What is XSLWhat is XSL
XSL (EXSL (Exxtensible tensible SStylesheet tylesheet LLanguage)anguage)Used to present the data of an XML-fileUsed to present the data of an XML-fileConsists of 3 parts:Consists of 3 parts:
XSLT (XSL Transformation)XSLT (XSL Transformation) XPath (Expression Language to access parts of the XML doc)XPath (Expression Language to access parts of the XML doc) XSL FO (XSL Formatting Objects)XSL FO (XSL Formatting Objects)
Different kind of outputDifferent kind of output htmlhtml pdfpdf txttxt
Can contain several scriptsCan contain several scripts JavascriptJavascript PerlscriptPerlscript
Template Album-SearchTemplate Album-Search<xsl:template match="album_search"><xsl:template match="album_search"> <h1>Album - Search - Result</h1><h1>Album - Search - Result</h1> <xsl:if test="result"><xsl:if test="result"> …… <th>number:</th><th align="left">title:</th><th align="left">interpret:</th><th align="left">genre:</th><th>number:</th><th align="left">title:</th><th align="left">interpret:</th><th align="left">genre:</th>
……<xsl:for-each select="//album"><xsl:for-each select="//album">
…… <td align="center"><b><xsl:value-of select="position()"/></b></td><td align="center"><b><xsl:value-of select="position()"/></b></td>
…… <td><A><td><A>
<xsl:attribute name="href"><xsl:attribute name="href">?<xsl:value-of select="//@parameter"/>?<xsl:value-of select="//@parameter"/>op=search&opt=interpret&interpret=op=search&opt=interpret&interpret=<xsl:value-of select="interpret"/><xsl:value-of select="interpret"/>
</xsl:attribute></xsl:attribute><xsl:value-of select="interpret"/></A></td><xsl:value-of select="interpret"/></A></td>
</xsl:for-each></xsl:for-each> </xsl:if></xsl:if> <xsl:if test="no_result"><xsl:if test="no_result"> <h4>No matching files for "<font color="#FF0000"><xsl:value-of select="//@album"/></font>" were <h4>No matching files for "<font color="#FF0000"><xsl:value-of select="//@album"/></font>" were
found! found! <br/><br/>Please try searching again!</h4><br/><br/><br/><br/>Please try searching again!</h4><br/><br/> <input type="button" name="New Search" value="New Search" onClick="history.back()"/> <input type="button" name="New Search" value="New Search" onClick="history.back()"/> </xsl:if></xsl:if>
</xsl:template></xsl:template>
Login-CheckLogin-Check
<xsl:template name="logincheck"><xsl:template name="logincheck"><xsl:if test="//@loggedIn='Yes'"><xsl:if test="//@loggedIn='Yes'"> <form action="?" method="get"><form action="?" method="get"> <input type="hidden" name="op" value="logout"/><input type="hidden" name="op" value="logout"/> <div align="center"><input type="submit" value="logout"/></div><div align="center"><input type="submit" value="logout"/></div> </form></form></xsl:if></xsl:if><xsl:if test="//@loggedIn='No'"><xsl:if test="//@loggedIn='No'"> <form action="?" method="get"><form action="?" method="get"> <input type="hidden" name="op" value="register"/><input type="hidden" name="op" value="register"/> <div align="center"><input type="submit„ value="Register"/></div><div align="center"><input type="submit„ value="Register"/></div> </form></form></xsl:if></xsl:if>
</xsl:template></xsl:template>
How did we use it?How did we use it?
1.1. Client sends a request to the ServletClient sends a request to the Servlet
2.2. JSP generates an XML-File JSP generates an XML-File
3.3. An universal XSL-Stylesheet matches An universal XSL-Stylesheet matches the generated XML-Filethe generated XML-File
4.4. Both are parsed online with XalanBoth are parsed online with Xalan
5.5. An HTML-File is send back to the An HTML-File is send back to the BrowserBrowser
Development StepsDevelopment Steps
WhatWhat features features shouldshould be be implementedimplemented
For each site/feature :For each site/feature : DTD (define tags and attributes)DTD (define tags and attributes)
Defined Tags & AttributesDefined Tags & Attributes
TagsTags Classic_searchClassic_search Interpret_searchInterpret_search Album_searchAlbum_search Track_searchTrack_search User_profileUser_profile MessageMessage loginCheckloginCheck WelcomeWelcome NewsNews DownloadDownload buybuy
AttributesAttributes loggedInloggedIn ParameterParameter
Development StepsDevelopment Steps
WhatWhat sites sites shouldshould be be implementedimplemented
For each function :For each function : DTD (define tags and attributes)DTD (define tags and attributes) XMLXML XSL-templateXSL-template
Main design of the webpageMain design of the webpage
Main PageMain Page
<xsl:template match="/"><xsl:template match="/"><html><html>
<head><head> <title>Shop</title><title>Shop</title> </head></head> <body><body>
<…><…>
Screenshot MainframeScreenshot Mainframe
Album-SearchAlbum-Search
ScenarioScenario
DBWebsite
InBrowser
JSP + Web server
A typical first visit to „CD-Now“A typical first visit to „CD-Now“
Pics +MP3
Open Location in Browser
User gets the welcome page
shopping chart
Cookies
Load on Demand
UserID stored in Cookie
Get information from DBin XML format
Server creates sessionand shopping chart
User browses the content of CD-Now
User gets the desired page
XML is parsed to HTMLusing an default XSLT
User decides to Subscribe to CD-Nowand provides the desired information
Create an UseraccountIn DB
Store UserID in session
UserID
User gets confirmationon success
UserID
User decides to set his preferencesand provides the desired information
Store preferences in session
Store preferences in DB
Prefs.
Prefs.User
From now on allXML is parsed to HTMLusing an personal XSLT
User wants to buyand download a music title
Bill the User andget the location of the
desired File
Bill
User is allowed dodownload th File
User may storeFile on Disk
HD
DBWebsite
InBrowser
JSP + Web server
A typical follow up visit to „CD-Now“A typical follow up visit to „CD-Now“
Pics +MP3
shopping chart
Cookies
UserID
UserID
Prefs.
Prefs.User
Bill
HD
Browser sends UserIDto Webserver
If no active Session is foundAn new one is created, readingpreferences from the DB
User gets personalwelcome message
User buysan MP3 User is requested
to authentificateby password
User authentificateshimself by password
Billing detail arestored in the DB
User is notifiedon success
User may nowdownload thedesired File
AgendaAgenda
IntroductionIntroduction
DemoDemo
Project cut in 2 partsProject cut in 2 parts1. Business logic & Presentation layer1. Business logic & Presentation layer
based on JSP/Servlets & XML/XSLbased on JSP/Servlets & XML/XSL
German Teams WorkGerman Teams Work
2. Backend Work2. Backend Workall Database Managementall Database Management
French Teams WorkFrench Teams Work
OutlookOutlook
MySQLMySQL
The RDBMS we used : MySQLThe RDBMS we used : MySQL
Numerous addons available:Numerous addons available: Administration through a web front-end : Administration through a web front-end :
PHPMyAdminPHPMyAdmin
JDBC drivers available, direct support from servlet JDBC drivers available, direct support from servlet runners like Resin, Tomcat, etc…runners like Resin, Tomcat, etc…
Free, rather powerful RDBMS.Free, rather powerful RDBMS.
Easy to set up.Easy to set up.
PHPMyAdmin viewPHPMyAdmin view
The data model in the MUSIC The data model in the MUSIC databasedatabase
CUSTOMER and ORDER are updated on the fly CUSTOMER and ORDER are updated on the fly as internet users register and order goods from as internet users register and order goods from our e-commerce siteour e-commerce site
4 main tables : ALBUM, CUSTOMER, 4 main tables : ALBUM, CUSTOMER, ORDERS, TRACKORDERS, TRACK
ALBUM and TRACK data have been imported fromALBUM and TRACK data have been imported from
a popular CD content database available a popular CD content database available
on the Internet : FREEDB (on the Internet : FREEDB (www.freedb.org))
Example : ALBUM TableExample : ALBUM Table
FreeDBFreeDB
The FreeDB database (1)The FreeDB database (1)
A few years ago, the CDDB popular A few years ago, the CDDB popular database was created (www.cddb.com), database was created (www.cddb.com), mainly for ripping audio CDs to mp3 mainly for ripping audio CDs to mp3 format with the right ID3 tagsformat with the right ID3 tags
These tags correspond to the artist name, genre, album title, These tags correspond to the artist name, genre, album title, track titles and so on…track titles and so on…
The primary key for getting the right data is the DiscIdThe primary key for getting the right data is the DiscId
Each audio CD holds a unique DiscIdEach audio CD holds a unique DiscId
Example of CDDB use : WinampExample of CDDB use : Winamp
The FreeDB database (2)The FreeDB database (2)
Here came FreeDB, the public domain Here came FreeDB, the public domain clone of CDDB. Holds now about 400.000 clone of CDDB. Holds now about 400.000 albums !!!albums !!!
Does not rely on a relational databaseDoes not rely on a relational database Very raw format (dirs and files)Very raw format (dirs and files) Not very well documentedNot very well documented
Unfortunately, CDDB become commercialUnfortunately, CDDB become commercial
in 1999, free access was closed.in 1999, free access was closed.
Example of a FreeDB fileExample of a FreeDB file# xmcd CD database file# xmcd CD database file
##
# Track frame offsets:# Track frame offsets:
## 150150
## 2321723217
## 4369143691
## 6612066120
## 8307583075
## 102804102804
## 120729120729
## 140522140522
## 161712161712
## 177744177744
## 198020198020
## 221391221391
## 240078240078
##
# Disc length: 3525 seconds# Disc length: 3525 seconds
##
# Revision: 0# Revision: 0
# Processed by: cddbd v1.4b41PL1 Copyright (c) Steve Scherf et al.# Processed by: cddbd v1.4b41PL1 Copyright (c) Steve Scherf et al.
# Submitted via: CD2WAV32(EN) R3.17# Submitted via: CD2WAV32(EN) R3.17
##
DISCID=aa0dc30dDISCID=aa0dc30d
DTITLE=SPITZ / RECYCLE Greatest Hits of SPITZDTITLE=SPITZ / RECYCLE Greatest Hits of SPITZ
DYEAR=1990DYEAR=1990
DGENRE=MISCDGENRE=MISC
TTITLE0=Kimi ga omoide ni naru maeniTTITLE0=Kimi ga omoide ni naru maeni
TTITLE1=Sora mo toberu hazuTTITLE1=Sora mo toberu hazu
TTITLE2=Aoi kurumaTTITLE2=Aoi kurumaTTITLE3=SpiderTTITLE3=SpiderTTITLE4=RobinsonTTITLE4=RobinsonTTITLE5=Namida ga kirariTTITLE5=Namida ga kirariTTITLE6=CherryTTITLE6=CherryTTITLE7=NagisaTTITLE7=NagisaTTITLE8=ScarletTTITLE8=ScarletTTITLE9=Yume ja naiTTITLE9=Yume ja naiTTITLE10=Unmei no hitoTTITLE10=Unmei no hitoTTITLE11=Tsumetai hohoTTITLE11=Tsumetai hohoTTITLE12=KaedeTTITLE12=KaedeEXTD=EXTD=EXTT0=EXTT0=EXTT1=EXTT1=EXTT2=EXTT2=EXTT3=EXTT3=EXTT4=EXTT4=EXTT5=EXTT5=EXTT6=EXTT6=EXTT7=EXTT7=EXTT8=EXTT8=EXTT9=EXTT9=EXTT10=EXTT10=EXTT11=EXTT11=EXTT12=EXTT12=PLAYORDER=PLAYORDER=
Problems encountered with FreeDBProblems encountered with FreeDB
We planned first to use a freeDB server.We planned first to use a freeDB server. We tried to set up a FreeDB server on the miageproject We tried to set up a FreeDB server on the miageproject
machine, without success.machine, without success. We then thought about using directly one of the numerous We then thought about using directly one of the numerous
freeDB serversfreeDB servers Problem : where to get the DiscId from ?Problem : where to get the DiscId from ?
Solution :Solution : We used a PHP script to import the FreeDB content to our We used a PHP script to import the FreeDB content to our MySQL database.MySQL database.Many advantages : indexing, complex requests now possible, Many advantages : indexing, complex requests now possible, import script can be run remotely (in order to update the import script can be run remotely (in order to update the ALBUM/TRACK content).ALBUM/TRACK content).
JDBCJDBC
Bridge java/MySQLBridge java/MySQL
Made through the JDBC API.Made through the JDBC API.
Servlets are run by the Resin/Caucho software.Servlets are run by the Resin/Caucho software.
Free for non commercial use, better than Tomcat (hot recompilation really Free for non commercial use, better than Tomcat (hot recompilation really works)works)
Easy to set up.Easy to set up.
Java code: Java code:
Class.forName("com.caucho.jdbc.mysql.Driver");Class.forName("com.caucho.jdbc.mysql.Driver");
String url = "jdbc:mysql-caucho://miageprojet:8085/music";String url = "jdbc:mysql-caucho://miageprojet:8085/music";
connection = DriverManager.getConnection(url,"music","wolfgang");connection = DriverManager.getConnection(url,"music","wolfgang");
Bridge with the German team (1)Bridge with the German team (1)
We wrote all the classes/methods that We wrote all the classes/methods that deal with the RDBMS.deal with the RDBMS.
Encapsulation of all the requests.Encapsulation of all the requests.
Kind of “black box“ made of 15 classesKind of “black box“ made of 15 classes
The German side corresponds only through 2 classesThe German side corresponds only through 2 classes
GetFromDatabaseGetFromDatabase
WriteToDatabaseWriteToDatabase
Bridge with the German team (2)Bridge with the German team (2)The parameters classesThe parameters classes
To get information from the DB :To get information from the DB :
SearchParameter classes :SearchParameter classes : SearchParameterAlbumSearchParameterAlbum SearchParameterCustomerSearchParameterCustomer SearchParameterOrdersSearchParameterOrders SearchParameterTrackSearchParameterTrack
To write / modify the DB :To write / modify the DB :
ParametersToWrite classes :ParametersToWrite classes :
… …
Bridge with the German team (3)Bridge with the German team (3)GetFromDatabase classGetFromDatabase class
Constructor gets SearchParameter objectConstructor gets SearchParameter object
GetFromDatabase gfdb=new GetFromDatabase gfdb=new GetFromDatabase(SearchParameter);GetFromDatabase(SearchParameter);Request started by :Request started by :
SearchParameter[ ][ ] sp = gfdb.getResult();SearchParameter[ ][ ] sp = gfdb.getResult();
getResult() :getResult() :
Gets SearchParameters valuesGets SearchParameters values
Makes the corresponding sql queryMakes the corresponding sql query
Connects the databaseConnects the database
Bridge with the German team (4)Bridge with the German team (4)WriteToDatabase classWriteToDatabase class
Constructor gets a ParametersToWrite object and the Constructor gets a ParametersToWrite object and the needed operationneeded operation
WriteToDatabase wtdb = new WriteToDatabase(WriteToDatabase wtdb = new WriteToDatabase(parameterToWrite ,parameterToWrite ,WriteToDatabase.UPDATEWriteToDatabase.UPDATE
););3 methods inside :3 methods inside :insert()insert()update()update()delete()delete()
Methods actions :Methods actions :
Get ParametersToWrite valuesGet ParametersToWrite valuesMake the corresponding sql operationMake the corresponding sql operationConnect the database and perform the operationConnect the database and perform the operation
Bridge with the German team (5)Bridge with the German team (5)
Looks simple ?Looks simple ?
However, fine tuning has been necessaryHowever, fine tuning has been necessary
Limit the amount of data transferred when a request produces a lot Limit the amount of data transferred when a request produces a lot of hitsof hits
Search web interface gets complex as the data model grew, Search web interface gets complex as the data model grew,
very complex requests need a sophisticated implementation…very complex requests need a sophisticated implementation…
JDBC/SQL is hard to debug (no typing, no checks JDBC/SQL is hard to debug (no typing, no checks at compilation time…) at compilation time…)
Better solution exists . SQL/J, java Blend, EJBs…Better solution exists . SQL/J, java Blend, EJBs…
AgendaAgenda
IntroductionIntroduction
DemoDemo
Project cut in 2 partsProject cut in 2 parts1. Business logic & Presentation layer1. Business logic & Presentation layer
based on JSP/Servlets & XML/XSLbased on JSP/Servlets & XML/XSL
German Teams WorkGerman Teams Work
2. Backend Work2. Backend Workall Database Managementall Database Management
French Teams WorkFrench Teams Work
OutlookOutlook
OutlookOutlook
Not all functionality implemented yetNot all functionality implemented yet CaddyCaddy BillingBilling ……
Automatic CD storingAutomatic CD storing
SecuritySecurity
Advanced and sophisticated queriesAdvanced and sophisticated queries
Thank you for your Thank you for your attention.attention.