Download Document

Document related concepts
no text concepts found
Transcript
Week 5
• Preliminaries to XML Messaging
Introductory Java Threads
A multi-threaded server
•XML Messaging
A PowerWarning application using SAX
• A DOM example
Building a DOM Tree from Scratch
Thread examples taken from “The Java Programming Language”
By Arnold and Gosling and from Cay Horstmann’s “Core Java 2
Advanced”. The PowerWarning Application is from “XML and
Internet Technologies
Java” by Maruyama, Tamura, and Uramoto,
Addison-Wesley.
Four kinds of thread programming
1) Unrelated threads
2) Related but unsynchronized threads
3) Mutually-exclusive threads
4) Communicating mutually-exclusive
threads
We will look at the first two (simple) kinds.
Internet Technologies
Unrelated threads
class Coffee extends Thread {
Coffee(String name) {
super(name);
}
public void run() {
for(int n = 1; n <= 3; n++) {
System.out.println("I like coffee");
yield();
System.out.println(this.getName());
yield();
}
}
}
Internet Technologies
class Tea extends Thread {
Tea(String name) {
super(name);
}
public void run() {
for(int n = 1; n <= 3; n++) {
System.out.println("I like tea");
yield();
System.out.println(this.getName());
yield();
}
}
}
Internet Technologies
public class Drinks {
public static void main(String args[]) {
System.out.println("I am main");
Coffee t1 = new Coffee("Wawa Coffee");
Tea t2 = new Tea(“Sleepy Time Tea");
t1.start();
t2.start();
System.out.println("Main is done");
}
}
Internet Technologies
Output
I am main
Main is done
I like coffee
I like tea
Wawa Coffee
Sleepy Time Tea
I like coffee
I like tea
Wawa Coffee
Sleepy Time Tea
I like coffee
I like tea
Wawa Coffee
Sleepy Time Tea
Main finishes right away
Threads are sharing time
This program has three threads.
Internet Technologies
Unrelated Threads Part II
• Using sleep() in unrelated threads
• The call sleep(millis) puts the currently executing thread to
sleep for at least the specified number of milliseconds. "At
least“ means there is no guarantee the thread will wake up
in exactly the specified time. Other thread scheduling can
interfere.
Internet Technologies
class Coffee extends Thread {
Coffee(String name) {
super(name);
}
public void run() {
for(int n = 1; n <= 3; n++) {
System.out.println("I like coffee");
try {
sleep(1000); // 1 second
}
catch(InterruptedException e) {}
System.out.println(this.getName());
}
}
}
Internet Technologies
class Tea extends Thread {
Tea(String name) {
super(name);
}
public void run() {
for(int n = 1; n <= 5; n++) {
System.out.println("I like tea");
System.out.println(getName());
}
}
}
Internet Technologies
public class Drinks2 {
public static void main(String args[]) {
System.out.println("I am main");
Coffee t1 = new Coffee("Wawa Coffee");
Tea t2 = new Tea(“Sleepy Time Tea");
t1.start();
t2.start();
System.out.println("Main is done");
}
}
Internet Technologies
I am main
Main is done
I like coffee
I like tea
Sleepy Time Tea
I like tea
Sleepy Time Tea
I like tea
Sleepy Time Tea
I like tea
Sleepy Time Tea
I like tea
Sleepy Time Tea
Wawa Coffee
I like coffee
Wawa Coffee
I like coffee
Wawa Coffee
After “I like coffee”,
the coffee thread
goes to sleep and the
tea thread gets to
finish and die.
1 second pausing
after each “I like
coffee”
Internet Technologies
Yield() and Sleep()
• Yield() may have no effect on some
implementations.
• The thread scheduler might make no
effort toward fairness.
• The yielding thread may be picked again
even though other threads want a turn.
• It is a good idea to call sleep() instead.
Internet Technologies
Ping Pong
•Adapted from "The Java Programming Language", Arnold
and Gosling
•After a thread is created, you can configure it – set its name,
its initial priority (system dependent), and so on.
•The start() method spawns a new thread of control based on
the data in the thread object and then returns.
• Now, the Java virtual machine invokes the new thread's run
method, making the thread active.
•When a thread's run method returns, the thread has exited.
•The thread may be manipulated with a number of methods,
including the interrupt() method as shown in this example.
Internet Technologies
Each PingPong object knows what to say and how long to sleep.
public class PingPong extends Thread {
private String word;
private int delay;
public PingPong(String whatToSay, int delayTime) {
word = whatToSay;
delay = delayTime;
}
Internet Technologies
public void run() {
try {
for(;;) {
System.out.println(word+" ");
sleep(delay);
}
}
catch (InterruptedException e) {
System.out.println("Interrupted!!!!!");
return;
}
}
Internet Technologies
public static void main(String args[]) {
PingPong t1 = new PingPong("\tping",33);
t1.start();
PingPong t2 = new PingPong("Pong",100);
t2.start();
try {
Thread.sleep(5000);
}
catch(InterruptedException e) {
// will not be printed
System.out.println("Good morning");
return;
}
Internet Technologies
Thread myThread = Thread.currentThread();
for (int t = 1 ; t <= 10; t++)
System.out.println("In Main..." + myThread.getName());
t1.interrupt();
}
}
Internet Technologies
C:\McCarthy\threads\PingPong>java PingPong
ping
Main is asleep.
Pong
ping
ping
ping
Pong
ping
ping
ping
For 5 seconds
Pong
ping and pong
ping
take turns sleeping
ping
and running
ping
:
:
Internet Technologies
Pong
ping
ping
ping
Pong
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
In Main...main
Interrupted!!!!!
Pong
Pong
Pong
Pong
Pong
:
Main wakes up
Main interrupts
Ping and ping dies.
“Pongs” forever
or until until ctrl-c
Internet Technologies
A Thread Application --A Simple Web
Server
• Responds by sending the same file on
each hit
• Creates a new thread on each hit
Internet Technologies
// A simple multi-threaded web server
import java.net.*;
import java.io.*;
import java.util.*;
public class OneFile extends Thread {
static String theData = "";
static String contentType;
static int contentLength;
Socket theConnection;
Internet Technologies
// construct each OneFile object with an existing socket
public OneFile(Socket s) {
theConnection = s;
}
// run the following code on each object
public void run() {
try {
// get a PrintStream attached to this socket
PrintStream os = new PrintStream(
theConnection.getOutputStream());
// get a DataInputStream attached to this socket
DataInputStream is = new DataInputStream(
theConnection.getInputStream());
// read a line from the socket
String request = is.readLine();
Internet Technologies
// HTTP/1.0 and later send a MIME header
if(request.indexOf("HTTP/") != -1) {
// we need to read the rest of the MIME header
while(true) {
String thisLine = is.readLine();
if(thisLine.trim().equals("")) break;
}
// respond to the client
os.print("HTTP/1.0 200 OK\r\n");
// send the date
Date now = new Date();
os.print("Date: " + now + "\r\n");
// send our name
os.print("Server: OneFile 1.0\r\n");
Internet Technologies
// send the contentLength
os.print("Content-length: " + contentLength + "\r\n");
// send the content type
os.print("Content-type: " + contentType + "\r\n\r\n");
}
// send the file in the string
os.println(theData);
theConnection.close();
}
catch(IOException e) {
}
}
Internet Technologies
// main loads the file and creates the object on every hit
public static void main(String args[] ) {
int thePort;
ServerSocket ss;
Socket theConnection;
FileInputStream theFile;
// cache the file
try {
// open file and create a DataInputStream
theFile = new FileInputStream(args[0]);
DataInputStream dis = new DataInputStream(theFile);
Internet Technologies
// determine the content type of this file
if(args[0].endsWith(".html") || args[0].endsWith(".htm") ) {
contentType = "text/html";
}
else {
contentType = "text/plain";
}
// read the file into the string theData
try {
String thisLine;
while((thisLine = dis.readLine()) != null) {
theData += thisLine + "\n";
}
}
catch(Exception e) {
System.err.println("Error " + e);
}
Internet Technologies
}
catch(Exception e) {
System.err.println(e);
System.err.println("usage: java onefile filename port");
System.exit(1);
}
// set the port to listen on
try {
thePort = Integer.parseInt(args[1]);
if(thePort < 0 || thePort > 65535) thePort = 80;
}
catch(Exception e) {
thePort = 80;
}
Internet Technologies
// create a server socket
try {
ss = new ServerSocket(thePort);
System.out.println("Accepting connections on port " +
ss.getLocalPort());
System.out.println("Data to be sent:");
System.out.println(theData);
while(true) {
// stop and wait for a connection
Socket socketTemp = ss.accept();
// we have a socket so create a handler
OneFile fs = new OneFile(socketTemp);
// start the handler running
Start thread
fs.start();
}
}
catch(IOException e) {System.out.println("Socket error"); }
}
}
Internet Technologies
Example: XML Messaging
The PowerWarning application allows users to register
their geographical position and their temperature concerns.
Users will receive e-mail when the temperature exceeds the user
specified parameters.
This example is from
“XML and Java” by Maruyama, Tamura, and Uramoto, Addison-Wesley.
Internet Technologies
Suppose that we know that the weather information is available
from the web at
http://www.xweather.com/White_Plains_NY_US.html.
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
<html>
<head>
<title>Weather Report</title>
</head>
<body>
<h2>Weather Report -- White Plains, NY </h2>
<table border=1>
<tr><td>Date/Time</td><td align=center>11 AM EDT Sat Jul 25
1998</td></tr>
[9]
<tr><td>Current Tem.</td><td align=center>70&#176;</td></tr>
[10]
<tr><td>Today’s High</td><td align=center>82&#176;</td></tr>
[11]
<tr><td>Today’s Low</td><td align=center>62&#176;</td><tr>
[12] </table>
[13] </body>
[14] </html>
Internet Technologies
•Strategy 1:
For the current temperature of White Plains, go to line 9,
column 46 of the page and continue until reaching the next
ampersand.
•Strategy 2:
For the current temperature of the White Plains, go to the
first <table> tag, then go to the second <tr> tag within the
table, and then go to the second <tg> tag within the row.
Neither of these seems very appealing…
Internet Technologies
<?xml version=“1.0”?>
<!DOCTYPE WeatherReport SYSTEM
“http>//www.xweather.com/WeatherReport.dtd”>
<WeatherReport>
<City>White Plains</City>
XML would help
<State>NY</State>
<Date>Sat Jul 25 1998</Date>
<Time>11 AM EDT</Time>
<CurrTemp unit=“Farenheit”>70</CurrTemp>
<High unit=“Farenheit”>82</High>
<Low unit=“Farenheit”>62</Low>
Internet Technologies
</Weather Report>
•Strategy 3:
For the current temperature of White Plains, N.Y., go
to the <CurrTemp> tag.
Internet Technologies
WeatherReport
application
Mobile users
XSLT
WML
HTML
XML
PC users
Http://www.xweather.com
PowerWarning
application
XML
Email notifications
XML
Application
programs
Registrations
Internet Technologies
The XML Describing the Weather
<?xml version="1.0" encoding="UTF-8"?>
This file is behind
<WeatherReport>
Jigsaw in the file
<City>Pittsburgh</City>
Www/weather/
<State>PA</State>
weather.xml.
<Date>Wed. April 11, 2001</Date>
<Time>3</Time>
<CurrTemp Unit = "Farenheit">70</CurrTemp>
<High Unit = "Farenheit">82</High>
Perhaps this is
<Low Unit = "Farenheit">62</Low>
being served up
</WeatherReport>
by www.xweather.com
for ½ cents per hit.
Internet Technologies
Serving the weather
// This servlet file is stored in Www/Jigsaw/servlet/GetWeather.java
// This servlet returns a user selected xml weather file from
// the Www/weather directory and returns it to the client.
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
This data would not
normally be retrieved
from a file.
It costs ½ cent per hit.
public class GetWeather extends HttpServlet {
Internet Technologies
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String theData = "";
/* For simplicity we get the user’s request from the path. */
String extraPath = req.getPathInfo();
extraPath = extraPath.substring(1);
// read the file
try {
// open file and create a DataInputStream
FileInputStream theFile =
new FileInputStream("c:\\Jigsaw\\Jigsaw\\”+
“Jigsaw\\Www\\weather\\"+extraPath);
Internet Technologies
InputStreamReader is = new InputStreamReader(theFile);
BufferedReader br = new BufferedReader(is);
// read the file into the string theData
String thisLine;
while((thisLine = br.readLine()) != null) {
theData += thisLine + "\n";
}
}
catch(Exception e) {
System.err.println("Error " + e);
}
PrintWriter out = res.getWriter();
out.write(theData);
System.out.println("Wrote document to client");
out.close();
}
}
Internet Technologies
WeatherReport
application
Mobile users
XSLT
WML
HTML
XML
PC users
Http://www.xweather.com
PowerWarning
application
XML
Email notifications
XML
Application
programs
Registrations
Internet Technologies
Registrations (HTML)
<!-- PowerWarningForm.html -->
<html>
<head>
<title>PowerWarning</title>
</head>
<body>
<form method="post" action="/servlet/PowerWarn">
E-Mail
<input type="text" name = "User"> <p>
State
<input type="text" name = "State"> <p>
City
<input type="text" name = "City"> <p>
Temperature
<input type="text" name = "Temperature"> <p>
Duration
<input type="text" name = "Duration"> <p>
<input type = "submit">
</form>
</body>
</html>
Internet Technologies
Registrations (Servlet)
The servlet will create a watcher object for each registered
user. The watcher object will be told of each user’s location
and temperature requirements. Each watcher object will run
in its own thread and may or may not notify its assigned
user by email.
On servlet initialization, we will start up an object whose
responsibility it is to periodically wake up and tell the watcher
objects to check the weather.
Internet Technologies
Registrations (Servlet)
/* This servlet is called by an HTML form. The form passes
the user email, state, city, temperature and duration.
*/
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class PowerWarn extends HttpServlet {
Internet Technologies
static Hashtable userTable;
/* Holds (email,watcher) pairs */
public void init(ServletConfig conf) throws ServletException {
super.init(conf);
PowerWarn.userTable = new Hashtable();
Scheduler scheduler = new Scheduler();
scheduler.start();
/* Run the scheduler */
}
/* The scheduler can see the hash
table. It has package access.
*/
Internet Technologies
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
/* Collect data from the HTML form */
String par_user =
String par_state =
String par_city =
int par_temp =
req.getParameter("User");
req.getParameter("State");
req.getParameter("City");
Integer.parseInt(
req.getParameter("Temperature"));
int par_duration = Integer.parseInt(
req.getParameter("Duration"));
Internet Technologies
/* Assign a watcher to this user. */
Watcher watcher = new Watcher(par_user, par_state, par_city,
par_temp, par_duration);
/* Place the (email,watcher) pair in the hash table. */
PowerWarn.userTable.put(par_user, watcher);
res.setContentType("text/html");
PrintWriter writer = res.getWriter();
writer.print("<html><head></head><body><b>” +
“You'll be notified by email</b></body></html>");
writer.close();
}
}
Internet Technologies
Servlet
Http Request
PowerWarn.userTable
Watcher
[email protected]
Email
User
data
Http Request
Watcher
User
data
[email protected]
Scheduler
Internet Technologies
Email
The Scheduler
import java.util.Enumeration;
public class Scheduler extends Thread {
public void run() {
System.out.println("Running scheduler");
while(true) {
Enumeration en = PowerWarn.userTable.elements();
while(en.hasMoreElements()) {
Watcher wa = (Watcher)en.nextElement();
new Thread(wa).start();
}
Internet Technologies
try {
/* put this thread to sleep for 15 seconds */
Thread.sleep(1000 * 15);
}
catch(InterruptedException ie) {
// ignore
}
} /* end while */
}
public Scheduler() {
super();
}
}
Internet Technologies
Fifteen seconds for
testing.
The Watcher Class
The Watcher objects make HTTP requests to get XML.
How should we handle the XML? SAX or DOM? SAX.
How do we send email? JavaMail.
Internet Technologies
import org.xml.sax.*;
import org.xml.sax.helpers.ParserFactory;
import java.io.*;
import java.net.*;
import org.w3c.dom.Document;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
Internet Technologies
public class Watcher extends HandlerBase implements Runnable {
String user, state, city;
int temp, duration, overTemp;
public Watcher(String user, String state, String city, int temp,
int duration) {
super();
this.user = user;
this.state = state;
this.city = city;
this.temp = temp;
this.duration = duration;
this.overTemp = 0;
}
Internet Technologies
public void run() { // called by scheduler
System.out.println("Running watcher");
/* Set up to call the weather service. */
String weatheruri =
“http://mccarthy.heinz.cmu.edu:8001/servlet/GetWeather”+
“/weather.xml";
/* For simplicity we won’t take the appropriate approach. */
/* String weatheruri =
"http://mccarthy.heinz.cmu.edu:8001/servlet/GetWeather/?city="
+ URLEncoder.encode(this.city);
*/
/* Create an InputSource object for the parser to use. */
InputSource is = new InputSource(weatheruri);
Internet Technologies
try {
/* Set up to handle incoming XML */
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
SAXParser parser = factory.newSAXParser();
parser.parse(is, this); /* The parser makes the calls. */
}
catch(Exception e) {
e.printStackTrace();
return;
}
/* The parsing and callbacks are done by this time. */
int currentTempNumber;
try {
currentTempNumber = Integer.parseInt(this.currentTemp.trim());
}
catch( NumberFormatException e) {e.printStackTrace(); return; }
Internet Technologies
/* See if the user wants to be alerted. */
if(currentTempNumber > this.temp) {
this.overTemp++;
if(this.overTemp >= this.duration) {
warning();
}
}
else {
this.overTemp = 0;
}
}
/* Send email via JavaMail. The Mailer class is based on the JavaMail API. */
public void warning() {
System.out.println("Sending email");
Mailer mailman = new Mailer(this.user,
"[email protected]", "It's hot");
mailman.send();
}
Internet Technologies
/* Handle SAX events. */
StringBuffer buffer;
String currentTemp;
public void startDocument() throws SAXException {
this.currentTemp = null;
}
public void startElement(String name, AttributeList aMap) throws SAXException {
if(name.equals("CurrTemp")) { /* Prepare for next event. */
this.buffer = new StringBuffer();
}
}
Internet Technologies
public void endElement(String name) throws SAXException {
if(name.equals("CurrTemp")) {
this.currentTemp = this.buffer.toString();
this.buffer = null;
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
if(this.buffer != null) this.buffer.append(ch,start,length);
}
}
Internet Technologies
WeatherReport
application
Mobile users
WML
HTML
XML
PC users
Http://www.xweather.com
PowerWarning
application
XML
Email notifications
XML
Application
programs
Registrations
Internet Technologies
Building a DOM Tree From Scratch
MyGradeBook.xml
<?xml version="1.0" encoding="UTF-8"?>
<GradeBook>
<Student>
<Score>100</Score>
</Student>
</GradeBook>
Internet Technologies
Let’s create this file
from within a java
program.
// DomExample.java
// Building an xml document from scratch
import java.io.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.*;
import com.sun.xml.tree.XmlDocument;
public class DomExample {
private Document document;
Internet Technologies
// Get an empty Document object
public DomExample () {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder()
document = builder.newDocument();
}
catch (Throwable t) {
t.printStackTrace ();
}
Internet Technologies
// Ask the Document object for various types of nodes and
// add them to the tree.
Element root = document.createElement("GradeBook");
document.appendChild(root);
Element student = document.createElement("Student");
root.appendChild(student);
Element score = document.createElement("Score");
student.appendChild(score);
Text value = document.createTextNode("100");
score.appendChild(value);
Internet Technologies
// Write the Document to disk.
try {
FileOutputStream fos = new
FileOutputStream("MyGradeBook.xml");
((XmlDocument)document).write(fos);
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
public static void main(String a[]) {
DomExample tree = new DomExample();
}
}
Internet Technologies