ppt - Computer Science and Engineering

advertisement
Visualizing the Data
Dr. Miguel A. Labrador
Department of Computer Science & Engineering
labrador@csee.usf.edu
http://www.csee.usf.edu/~labrador
1
Outline
•
•
•
•
•
•
The big picture
Google Web Toolkit (GWT)
GWT development process
AJAX RPC approach
Client code
Sever code
2
Copyright© Dr. Miguel A. Labrador
2
Visualization
• Our tracking application includes a “main control station”
connected to the Internet to visualize the position of the users in
real time
– Google Web Toolkit and Google Maps
3
Copyright© Dr. Miguel A. Labrador
3
The Big Picture
• Client code
– Runs in main control station
– Sends queries to the server asking for the coordinates of all active
sessions
– Upon reception of coordinates, it shows them in a Google Map
• Server code
– Implements an interface that listens for queries asking for
coordinates
– Once a query is received, it connects to the database and retrieves
the last coordinates of all active sessions
– Sends an array of coordinates back to the client
• Key aspect is the communication part
– GWT provides an easy approach to make RPC calls to the server
• AJAX RPC Approach
4
Copyright© Dr. Miguel A. Labrador
4
Google Web Toolkit
• The Google Web Toolkit is a framework to create dynamic and
interactive Web applications
– Code is written in Java
– Parts of a GWT application execute in the Web client (browser) and
other parts in the Web server
• The part that executes in the Web client runs in JavaScript
• The GWT compiles Java into JavaScript
• Client code developed in Eclipse and GWT
– Once compiled, it has to be copied in the server so it can be
deployed in the Internet
• Server code developed in NetBeans
5
Copyright© Dr. Miguel A. Labrador
5
GWT Development Process
Server
Side
Client
Side
6
Copyright© Dr. Miguel A. Labrador
6
The AJAX RPC Approach
GWT Client Application
Service Interface
related
Server
Service Interface
Asynchronous Interface
implements
implements
Class Service Proxy
Implementation
(generated by GWT)
HTTP
Class Service
Implementation (written
by the programmer)
7
Copyright© Dr. Miguel A. Labrador
7
The AJAX RPC Approach
Client Side Code
• Service interface
– Abstracts the methods that can be invoked by a client
– Each service interface defines the functions that the system
implements
• Asynchronous interface
– Abstracts the methods that are actually invoked by the client
• It is related to the service interface
– Needed not to block the Web browser
• Class service proxy or client-side service implementation
– Class that actually invokes the RPC procedure
– Automatically generated by GWT
– Implements the data serialization over HTTP
8
Copyright© Dr. Miguel A. Labrador
8
The AJAX RPC Approach
Server Side Code
• Class service implementation or server-side service
implementation
– Class that implements the service interface in the server
– Executes in the server when a client invokes a method of the RPC
service interface
• Two important aspects of the GWT AJAX RPC approach:
– GWT serializes the objects for you
– GWT transmits the objects back and forth for you
9
Copyright© Dr. Miguel A. Labrador
9
Client Side Project
• Creating a new project in Eclipse
– Open a cmd line window in directory where GWT was installed and
type:
projectCreator -eclipse LbsBookGWT -out LbsBookGWT
applicationCreator -eclipse LbsBookGWT -out LbsBookGWT cse.usf.edu.book.client.GwtBook
• Import project into Eclipse’s workspace
– Run it to check it was imported successfully
10
Copyright© Dr. Miguel A. Labrador
10
Client Side Project
• Eclipse creates an application skeleton with two packages and
several files (see Package Explorer)
11
Copyright© Dr. Miguel A. Labrador
11
Client Side Project Skeleton Files
• Eclipse creates a basic application
– Skeleton packages and files that need to be modified to make your
own application
• Package cse.usf.edu.book contains all Web pages and images
– Contains GetBook.css file
• Cascade Style File with style of all html objects
– Contains the GwtBook.html file that loads the GWT module in the
browser and invokes the application
– Contains GwtBook.gwt.xml file
• Contains information that GWT use to compile and link libraries
• Defines application entry point
• Package cse.usf.edu.book.client contains the Java source
code of the client application
– File GwtBook.java serves as the entry point of the application
• Your application
12
Copyright© Dr. Miguel A. Labrador
12
Configuring a GWT Project
• In order to utilize the Google Maps API in GWT, the following
steps have to be followed:
– Sign up for a Google Maps key for the URL where the application
will be deployed
• http://code.google.com/apis/maps/
– Download the Google Maps API library for GWT
• http://code.google.com/p/wgt-google-apis/
– Import the library into the GWT Eclipse Project
• Add gwt-maps.jar file to the GWT project
– Open Eclipse, go to Package Explorer, right click on the project’s
name and click on Properties
– Select Java Build Path and click on the Libraries tab panel
– Click on Add external JAR and find the gwt-maps.jar file that you
downloaded
– Click Open and Ok
13
Copyright© Dr. Miguel A. Labrador
13
Configuring a GWT Project
• In order to utilize the Google Maps API in GWT, the following
steps have to be followed:
– Configure the GWT project .xml file and develop your code
• Open the GwtBook.gwt.xml file and include your key
<module>
<!-- Inherit the core Web Toolkit stuff.
<inherits name='com.google.gwt.user.User'/>
-->
<!-- Inherit the default GWT style sheet.
-->
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
<!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
<!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>
-->
<inherits name='com.google.gwt.maps.GoogleMaps'/>
<!-- Specify the app entry point class.
<entry-point class='cse.usf.edu.book.client.GwtBook'/>
-->
<!-- Specify the application specific style sheet.
-->
<stylesheet src='GwtBook.css' />
<script src="http://maps.google.com/maps?gwt=1&file=api&v=2&key=Your key"/>
</module>
14
Copyright© Dr. Miguel A. Labrador
14
The GwtBook.html File
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!--->
<!-- Any title is fine
-->
<!--->
<title>GwtBook</title>
<!-- This script loads your compiled module.
-->
<script type="text/javascript" language="javascript"
src="cse.usf.edu.book.GwtBook.nocache.js"></script>
</head>
<!-<!-- The body can have arbitrary html, or
<!-- you can leave the body empty if you want
<body>
-->
-->
-->
<!-- OPTIONAL: include this if you want history support -->
<iframe src="javascript:" id="__gwt_historyFrame" tabIndex='-1'
style="position:absolute;width:0;height:0;border:0"></iframe>
</body>
</html>
15
Copyright© Dr. Miguel A. Labrador
15
The GwtBook.java File
package cse.usf.edu.book.client;
import
import
import
import
import
import
import
import
com.google.gwt.core.client.EntryPoint;
com.google.gwt.user.client.ui.Button;
com.google.gwt.user.client.ui.ClickListener;
com.google.gwt.user.client.ui.DialogBox;
com.google.gwt.user.client.ui.Image;
com.google.gwt.user.client.ui.RootPanel;
com.google.gwt.user.client.ui.VerticalPanel;
com.google.gwt.user.client.ui.Widget;
public class GwtBook implements EntryPoint {
public void onModuleLoad() {
Image img = new Image("http://code.google.com/webtoolkit/logo-185x175.png");
Button button = new Button("Click me");
// We can add style names
button.addStyleName("pc-template-btn");
// or we can set an id on a specific element for styling
img.getElement().setId("pc-template-img");
VerticalPanel vPanel = new VerticalPanel();
vPanel.setWidth("100%");
vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
vPanel.add(img);
vPanel.add(button);
16
Copyright© Dr. Miguel A. Labrador
16
The GwtBook.java File
// Add image and button to the RootPanel
RootPanel.get().add(vPanel);
// Create the dialog box
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Welcome to GWT!");
dialogBox.setAnimationEnabled(true);
Button closeButton = new Button("close");
VerticalPanel dialogVPanel = new VerticalPanel();
dialogVPanel.setWidth("100%");
dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
dialogVPanel.add(closeButton);
closeButton.addClickListener(new ClickListener(){
public void onClick(Widget sender)
{
dialogBox.hide();
}});
// Set the contents of the Widget
dialogBox.setWidget(dialogVPanel);
button.addClickListener(new ClickListener(){
public void onClick(Widget sender)
{
dialogBox.center();
dialogBox.show();
}});
}
}
17
Copyright© Dr. Miguel A. Labrador
17
18
Copyright© Dr. Miguel A. Labrador
18
Client Side Code
• You need to modify these skeleton files to make your own
application
• In our case, we need to develop an application that will query
the server (database) for the last positions of the active users
and display them in a Google map
• The steps are the following:
– Main tracking component
– Create a serializable object that will contain the information from
the database and methods to operate on the object
– Create client service interface with the functions or services to be
implemented
– Create the Asynchronous service interface
– Develop the code that will implement the methods
– Modify the skeleton files
• GWT .xml file, onModuleLoad()
19
Copyright© Dr. Miguel A. Labrador
19
Main Tracking Component
package cse.usf.edu.book.client;
import
import
import
import
import
import
import
com.google.gwt.maps.client.MapWidget;
com.google.gwt.maps.client.control.LargeMapControl;
com.google.gwt.maps.client.control.MapTypeControl;
com.google.gwt.maps.client.geom.LatLng;
com.google.gwt.maps.client.overlay.Marker;
com.google.gwt.user.client.*;
com.google.gwt.user.client.ui.*;
public class TrackingWindow extends Composite {
private AbsolutePanel backgroundPanel = null;
private MapWidget theMapWidget = null;
public TrackingWindow() {
super();
initializeComponents();
setLayout();
setProperties();
LatLng coordinates = LatLng.newInstance(28.055166, -82.413511);
Marker theNewMarker = new Marker(coordinates);
theMapWidget.addOverlay(theNewMarker);
theMapWidget.setZoomLevel(14);
theMapWidget.setCenter(coordinates);
}
20
Copyright© Dr. Miguel A. Labrador
20
Main Tracking Component
protected void initializeComponents(){
backgroundPanel = new AbsolutePanel();
theMapWidget = new MapWidget();
backgroundPanel.add(theMapWidget,1,1);
}
protected void setLayout(){
initWidget(backgroundPanel);
}
protected void setProperties(){
setHeight("600");
setWidth("800");
backgroundPanel.setHeight("600");
backgroundPanel.setWidth("800");
theMapWidget.setHeight("600");
theMapWidget.setWidth("800");
theMapWidget.addControl(new LargeMapControl());
theMapWidget.addControl(new MapTypeControl());
}
public void updateActiveSessions()
{
}
21
}
Copyright© Dr. Miguel A. Labrador
21
Serializable Object
package cse.usf.edu.book.client.entities;
import com.google.gwt.user.client.rpc.IsSerializable;
public class TrackingUpdate implements IsSerializable{
private double latitude;
private double longitude;
private int sessionid;
private String username;
public TrackingUpdate(){}
public int getsessionId(){return sessionid;}
public String getUsername(){return username;}
public double getLatitude(){return latitude;}
public double getLongitude(){return longitude;}
public void setSessionid(int sessionid){this.sessionid = sessionid;}
public void setUsername(String usr){this.username = usr;}
public void setLatitude(double lat){this.latitude = lat;}
public void setLongitude(double lng){this.longitude = lng;}
22
}
Copyright© Dr. Miguel A. Labrador
22
Service and Asynchronous Service Interfaces
package cse.usf.edu.book.client.services;
import com.google.gwt.user.client.rpc.RemoteService;
import cse.usf.edu.book.client.entities.TrackingUpdate;
public interface TrackingServiceManager extends RemoteService{
public TrackingUpdate[] getTrackingUpdates();
}
package cse.usf.edu.book.client.services;
import com.google.gwt.user.client.rpc.AsyncCallback;
import cse.usf.edu.book.client.entities.TrackingUpdate;
public interface TrackingServiceManagerAsync {
public void getTrackingUpdates(AsyncCallback callback);
}
23
Copyright© Dr. Miguel A. Labrador
23
Method Implementation
public void updateActiveSessions()
{
TrackingServiceManagerAsync theTrackingManager =
(TrackingServiceManagerAsync) GWT.create(TrackingServiceManager.class);
ServiceDefTarget endpoint = (ServiceDefTarget) theTrackingManager;
String remoteServiceURL =
"http://192.168.0.2:8080/Lbsbook/services/TrackingManager";
endpoint.setServiceEntryPoint(remoteServiceURL);
AsyncCallback callback = new AsyncCallback(){
public void onSuccess(Object result){
TrackingUpdate theUpdates[] = (TrackingUpdate[]) result;
24
Copyright© Dr. Miguel A. Labrador
24
Method Implementation
if(theUpdates != null)
{
theMapWidget.clearOverlays();
for(int i = 0; i < theUpdates.length; i++)
{
final LatLng coordinates =
LatLng.newInstance(theUpdates[i].getLatitude(), theUpdates[i].getLongitude());
final String theString =
"Username: "+theUpdates[i].getUsername()+"<br>Session id:
"+theUpdates[i].getsessionId();
Marker theNewMarker = new Marker(coordinates);
MarkerClickHandler theHandler = new MarkerClickHandler(){
public void onClick(MarkerClickEvent event) {
theMapWidget.getInfoWindow().open(coordinates,
new InfoWindowContent(theString));
}
};
25
Copyright© Dr. Miguel A. Labrador
25
Method Implementation
theNewMarker.addMarkerClickHandler(theHandler);
theMapWidget.addOverlay(theNewMarker);
}
}
}
public void onFailure(Throwable caught){
Window.alert("An Internal Error has ocurred: " + caught.getMessage());
}
};
theTrackingManager.getTrackingUpdates(callback);
}
26
Copyright© Dr. Miguel A. Labrador
26
Get the Positions Periodically
• Need to modify the initializeComponents() method to include a
timer to query for the active sessions every 10 seconds
// this code assumes that there is a field in the class called trackingTimer.
// to do this, add the following field Timer trackingTimer to the class.
protected void initializeComponents(){
backgroundPanel = new AbsolutePanel();
theMapWidget = new MapWidget();
backgroundPanel.add(theMapWidget, 1,1);
trackingTimer = new Timer()
{
public void run()
{
updateActiveSessions();
}
};
trackingTimer.scheduleRepeating(10000);
}
27
Copyright© Dr. Miguel A. Labrador
27
Server Side Code
• Server code consists of the same serializable class and
implementation of the service interface and the methods that,
upon the invocation from the client, implement the requested
functions in the server
– All these developed in NetBeans
• First step is to create a new project in NetBeans
– New Java Web Application
• Add GWT Library to your Project
– Add the gwt-servelt.jar file in the GWT installation directory
28
Copyright© Dr. Miguel A. Labrador
28
Server Side Code
• Next is to create the serializable class TrackingUpdate
– Same name and code as the client
– Under the same package cse.usf.edu.book.client.entities
• Next is to create the corresponding service interface
– Create a package with the same name as the package that contains
the service interface in the client
• cse.usf.edu.book.client.services
– Create an interface just as the one created for the client but with the
“Impl” suffix
• TrackingServiceManagerImpl
• Implements the methods defined in the service interface
– Only one: getTrackingUpdates() method
• This includes the code that upon the client’s request, will query the
database and return the list of GPS fixes
– The fixes will be sent in the serializable object
– The transmission of the object is completely hidden to the
programmer!!!
29
Copyright© Dr. Miguel A. Labrador
29
The TrackingServiceManagerImpl Method
package cse.usf.edu.book.client.services;
import
import
import
import
import
import
import
import
import
import
import
import
import
com.google.gwt.user.server.rpc.RemoteServiceServlet;
cse.usf.edu.book.client.entities.TrackingUpdate;
java.sql.Connection;
java.sql.PreparedStatement;
java.sql.ResultSet;
java.sql.SQLException;
java.util.Iterator;
java.util.LinkedList;
java.util.List;
java.util.logging.Level;
java.util.logging.Logger;
javax.naming.NamingException;
org.postgis.Point;
public class TrackingServiceManagerImpl extends RemoteServiceServlet
implements TrackingServiceManager{
30
Copyright© Dr. Miguel A. Labrador
30
The TrackingServiceManagerImpl Method
public TrackingUpdate[] getTrackingUpdates()
{
try{
javax.naming.InitialContext ic = new javax.naming.InitialContext();
javax.sql.DataSource dataSource = (javax.sql.DataSource)ic.lookup("jdbc/lbsbook");
Connection theConnection = dataSource.getConnection();
PreparedStatement queryStatement = theConnection.prepareStatement
("select fieldsession.sessionid as sesid, fielduser.username as uname,
ST_AsText(tracking.position) as pos from fieldsession, tracking,fielduser,
(select max(idtracking) as idtrack from fieldsession, tracking
where fieldsession.datestop is NULL and
fieldsession.sessionid=tracking.sessionid
group by fieldsession.sessionid) as s2 "+
"where fieldsession.datestop is NULL and
fieldsession.sessionid = tracking.sessionid and "+
"tracking.idtracking = s2.idtrack and
fieldsession.iduser = fielduser.iduser");
31
Copyright© Dr. Miguel A. Labrador
31
The TrackingServiceManagerImpl Method
ResultSet rs = queryStatement.executeQuery();
List returnList = new LinkedList();
while(rs.next()){
TrackingUpdate newUpdate = new TrackingUpdate();
newUpdate.setSessionid(rs.getInt("sesid"));
newUpdate.setUsername(rs.getString("uname"));
Point theNewPoint = new Point(rs.getString("pos"));
newUpdate.setLongitude(theNewPoint.getX());
newUpdate.setLatitude(theNewPoint.getY());
returnList.add(newUpdate);
}
theConnection.close();
32
Copyright© Dr. Miguel A. Labrador
32
The TrackingServiceManagerImpl Method
if(!returnList.isEmpty())
{
TrackingUpdate theReturnVector[] = new TrackingUpdate[returnList.size()];
int i = 0;
for (Iterator it = returnList.iterator(); it.hasNext();)
{
TrackingUpdate theUpdate = (TrackingUpdate) it.next();
theReturnVector[i] = theUpdate;
i++;
}
return theReturnVector;
}
return null;
}
catch (NamingException ex){
Logger.getLogger(DevicerServiceManagerImpl.class.getName())
.log(Level.SEVERE, null, ex);
}
catch (SQLException ex){
Logger.getLogger(DevicerServiceManagerImpl.class.getName())
.log(Level.SEVERE, null, ex);
}
return null;
}
}
33
Copyright© Dr. Miguel A. Labrador
33
Server Side Code
• Once the project, classes, packages, interfaces, and
implementations are ready, the next step is to register the
implementation with the Web application deployment descriptor
– Go to the Project panel, click on the + sign of the label Configuration
and double click over the web.xml file
– A page that contains the configuration of the application appears on
the right side. Click on the Servlets button and click the Add Servlet
Element button
– In the window, write GwtTrackingManager in the Name textfield. In
the Servlet class click on the Browse button and look for the
TrackingServiceManagerImpl.java class. In URL Pattern(s) write
/services/TrackingManager.
– At this point, the server side code can be deployed
– When deployed, the URL of the TrackingManager will be
http://ip_machine:port/lab5/services/TrackingManager. This URL will
be used by the client to invoke the service
34
Copyright© Dr. Miguel A. Labrador
34
Final Step
• Now that the client and server codes have been developed, it is
time to compile the application with GWT and deploy it along
with the Web Project. The following steps indicate how to
accomplish this:
– Compile the Eclipse project with GWT: Run the Eclipse project and
click on the Compile/Browse button
– Copy the compiled files to the Web project application
• Using the Windows Explorer, go to the Eclipse's GWT project location
and copy the folder www to the Web folder of the NetBeans project
– Build and Deploy
• Using NetBeans, build and deploy the Web project
• After the Web application has been deployed, it can be
executed from a Web browser. In our case the URL to use
would be http://ip_machine:port/lab5/services/TrackingManager;
which consists of the path where the application resides in the
server with IP address ip_machine:port.
35
Copyright© Dr. Miguel A. Labrador
35
Download