Exercises

Included below are short-answer and programming exercises. Answers are provided for those exercises whose exercise number is a hyperlink. Because college faculty use these exercises in their exams, we have provided answers to roughly half of the exercises included here.


20.3 The current implementation of class TemperatureServerImpl downloads the weather information only once. Modify class TemperatureServerImpl to obtain weather information from the National Weather Service twice a day.

20.4 Modify interface TemperatureServer to include support for obtaining the current day's forecast and the next day's forecast. Study the Travelers Forecast Web page

http://iwin.nws.noaa.gov/iwin/us/traveler.html

at the NWS Web site for the format of each line of information. Next, modify class TemperatureServerImpl to implement the new features of the interface. Finally, modify class TemperatureClient to allow the user to select the weather forecast for either day. Modify the support classes WeatherInfo and WeatherItem as necessary to support the changes to classes TemperatureServerImpl and TemperatureClient.

20.5 (Project: Weather for Your State) There is a wealth of weather information on the National Weather Service Web site. Study the following Web pages:

http://iwin.nws.noaa.gov/
http://iwin.nws.noaa.gov/iwin/textversion/main.html

and create a complete weather forecast server for your state. Design your classes for reusability.

20.6 (Project: Weather for Your State) Modify the Exercise 20.5 project solution to allow the user to select the weather forecast for any state.

20.7 (For international readers) If there is a similar World Wide Web-based weather service in your own country, provide a different TemperatureServerImpl implementation with the same remote interface TemperatureServer (Fig. 20.1). The server should return weather information for major cities in your country.

20.8 (Remote Phone Book Server) Create a remote phone book server that maintains a file of names and phone numbers. Define interface PhoneBookServer with the following methods:

public PhoneBookEntry[] getPhoneBook()
public void addEntry( PhoneBookEntry entry )
public void modifyEntry( PhoneBookEntry entry )
public void deleteEntry( PhoneBookEntry entry )

Class PhoneBookServerImpl should implement interface PhoneBookServer. Class PhoneBookEntry should contain String instance variables that represent the first name, last name and phone number for one person. The class should also provide appropriate set/get methods and perform validation on the phone number format. Remember that class PhoneBookEntry must also implement Serializable so objects of this class can be serialized by RMI.

Class PhoneBookClient should define a user interface that allows the user to scroll through entries, add a new entry, modify an existing entry and delete an existing entry. The client and the server should provide proper error handling (e.g., the client cannot modify an entry that does not exist).


Selected Answers

Included below are answers to approximately half the of the exercises in the Cyber Classroom. We are not able to include answers to every exercise because college faculty use these exercises in their classroom exams.


20.3

import java.util.*;public class T {   public static void main( String args[] )   {      // Get a calendar based upon Eastern Standard Time      Calendar c = new GregorianCalendar( TimeZone.getTimeZone( "EST" )  );      // Get hour, minute and second      System.err.println( c.get( Calendar.HOUR_OF_DAY ) );      System.err.println( c.get( Calendar.MINUTE ) );      System.err.println( c.get( Calendar.SECOND ) );      System.err.println( 60 - c.get( Calendar.SECOND ) );      System.err.println( 60 - c.get( Calendar.MINUTE ) );      System.err.println( 11 - c.get( Calendar.HOUR_OF_DAY ) );   }}// Exercise 20.3 Solutionimport java.rmi.*;import java.io.Serializable;public class WeatherInfo implements Serializable {   private String cityName;   private String temperature;   private String description;   public WeatherInfo( String city, String desc, String temp )   {      cityName = city;      temperature = temp;      description = desc;   }   public String getCityName() { return cityName; }   public String getTemperature() { return temperature; }   public String getDescription() { return description; }}/************************************************************************** * (C) Copyright 1999 by Deitel & Associates, Inc. and Prentice Hall.     * * All Rights Reserved.                                                   * *                                                                        * * DISCLAIMER: The authors and publisher of this book have used their     * * best efforts in preparing the book. These efforts include the          * * development, research, and testing of the theories and programs        * * to determine their effectiveness. The authors and publisher make       * * no warranty of any kind, expressed or implied, with regard to these    * * programs or to the documentation contained in these books. The authors * * and publisher shall not be liable in any event for incidental or       * * consequential damages in connection with, or arising out of, the       * * furnishing, performance, or use of these programs.                     * *************************************************************************/// Exercise 20.3 Solutionimport java.awt.*;import javax.swing.*;public class WeatherItem extends JLabel {    private static ImageIcon weatherImages[], backgroundImage;   private final static String weatherConditions[] =      { "SUNNY", "PTCLDY", "CLOUDY", "MOCLDY", "TSTRMS",        "RAIN", "SNOW", "VRYHOT", "FAIR", "RNSNOW",        "SHWRS", "WINDY", "NOINFO", "MISG" };   private final static String weatherImageNames[] =      { "sunny", "pcloudy", "mcloudy", "mcloudy", "rain",        "rain", "snow", "vryhot", "fair", "rnsnow",        "showers", "windy", "noinfo", "noinfo" };   // static initializer block to load weather images   static {      backgroundImage = new ImageIcon( "images/back.jpg" );      weatherImages =         new ImageIcon[ weatherImageNames.length ];      for ( int i = 0; i < weatherImageNames.length; ++i )         weatherImages[ i ] = new ImageIcon(             "images/" + weatherImageNames[ i ] + ".jpg" );   }     // instance variables   private ImageIcon weather;   private WeatherInfo weatherInfo;   public WeatherItem( WeatherInfo w )   {      weather = null;      weatherInfo = w;      // locate image for city's weather condition      for ( int i = 0; i < weatherConditions.length; ++i )           if ( weatherConditions[ i ].equals(              weatherInfo.getDescription().trim() ) ) {            weather = weatherImages[ i ];            break;         }      // pick the "no info" image if either there is no      // weather info or no image for the current      // weather condition      if ( weather == null ) {           weather = weatherImages[ weatherImages.length - 1 ];         System.err.println( "No info for: " +                             weatherInfo.getDescription() );      }   }   public void paintComponent( Graphics g )   {      super.paintComponent( g );      backgroundImage.paintIcon( this, g, 0, 0 );      Font f = new Font( "SansSerif", Font.BOLD, 12 );      g.setFont( f );      g.setColor( Color.white );      g.drawString( weatherInfo.getCityName(), 10, 19 );      g.drawString( weatherInfo.getTemperature(), 130, 19 );      weather.paintIcon( this, g, 253, 1 );   }   // make WeatherItem's preferred size the width and height of   // the background image   public Dimension getPreferredSize()   {      return new Dimension( backgroundImage.getIconWidth(),                            backgroundImage.getIconHeight() );   }}/************************************************************************** * (C) Copyright 1999 by Deitel & Associates, Inc. and Prentice Hall.     * * All Rights Reserved.                                                   * *                                                                        * * DISCLAIMER: The authors and publisher of this book have used their     * * best efforts in preparing the book. These efforts include the          * * development, research, and testing of the theories and programs        * * to determine their effectiveness. The authors and publisher make       * * no warranty of any kind, expressed or implied, with regard to these    * * programs or to the documentation contained in these books. The authors * * and publisher shall not be liable in any event for incidental or       * * consequential damages in connection with, or arising out of, the       * * furnishing, performance, or use of these programs.                     * *************************************************************************/// Exercise 20.3 Solution import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.rmi.*;   public class TemperatureClient extends JFrame{   public TemperatureClient( String ip )    {      super( "RMI TemperatureClient..." );            getRemoteTemp( ip );        setSize( 625, 567 );      setResizable( false );      show();   }   // obtain weather information from TemperatureServerImpl   // remote object   private void getRemoteTemp( String ip )   {               try {         // name of remote server object bound to rmi registry         String serverObjectName = "//" + ip + "/TempServer";          // lookup TemperatureServerImpl remote object         // in rmiregistry         TemperatureServer mytemp = ( TemperatureServer )             Naming.lookup( serverObjectName );         // get weather information from server         WeatherInfo weatherInfo[] = mytemp.getWeatherInfo();         WeatherItem w[] =            new WeatherItem[ weatherInfo.length ];         ImageIcon headerImage =            new ImageIcon( "images/header.jpg" );         JPanel p = new JPanel();         // determine number of rows for the GridLayout;         // add 3 to accommodate the two header JLabels         // and balance the columns         p.setLayout(            new GridLayout( ( w.length + 3 ) / 2, 2 ) );         p.add( new JLabel( headerImage ) ); // header 1         p.add( new JLabel( headerImage ) ); // header 2         for ( int i = 0; i < w.length; i++ ) {               w[ i ] = new WeatherItem( weatherInfo[ i ] );            p.add( w[ i ] );                    }         getContentPane().add( new JScrollPane( p ),                             BorderLayout.CENTER );      }      catch ( java.rmi.ConnectException ce ) {         System.err.println( "Connection to server failed. " +            "Server may be temporarily unavailable." );      }      catch ( Exception e ) {          e.printStackTrace();         System.exit( 1 );       }         }   public static void main( String args[] )   {      TemperatureClient gt = null;      // if no sever IP address or host name specified,      // use "localhost"; otherwise use specified host      if ( args.length == 0 )         gt = new TemperatureClient( "localhost" );      else         gt = new TemperatureClient( args[ 0 ] );      gt.addWindowListener(         new WindowAdapter() {            public void windowClosing( WindowEvent e )            {               System.exit( 0 );            }         }      );   }}/************************************************************************** * (C) Copyright 1999 by Deitel & Associates, Inc. and Prentice Hall.     * * All Rights Reserved.                                                   * *                                                                        * * DISCLAIMER: The authors and publisher of this book have used their     * * best efforts in preparing the book. These efforts include the          * * development, research, and testing of the theories and programs        * * to determine their effectiveness. The authors and publisher make       * * no warranty of any kind, expressed or implied, with regard to these    * * programs or to the documentation contained in these books. The authors * * and publisher shall not be liable in any event for incidental or       * * consequential damages in connection with, or arising out of, the       * * furnishing, performance, or use of these programs.                     * *************************************************************************/// Exercise 20.3 Solutionimport java.rmi.*;public interface TemperatureServer extends Remote {   public WeatherInfo[] getWeatherInfo()      throws RemoteException;}/************************************************************************** * (C) Copyright 1999 by Deitel & Associates, Inc. and Prentice Hall.     * * All Rights Reserved.                                                   * *                                                                        * * DISCLAIMER: The authors and publisher of this book have used their     * * best efforts in preparing the book. These efforts include the          * * development, research, and testing of the theories and programs        * * to determine their effectiveness. The authors and publisher make       * * no warranty of any kind, expressed or implied, with regard to these    * * programs or to the documentation contained in these books. The authors * * and publisher shall not be liable in any event for incidental or       * * consequential damages in connection with, or arising out of, the       * * furnishing, performance, or use of these programs.                     * *************************************************************************/// Exercise 20.3 Solutionimport java.rmi.*;import java.rmi.server.*;import java.util.*;import java.io.*;import java.net.*;public class TemperatureServerImpl extends UnicastRemoteObject       implements TemperatureServer, Runnable {   private WeatherInfo weatherInformation[];   private Thread t;   private Calendar c;   private TimeDelay delay;   private int dh, dm, ds;   public TemperatureServerImpl() throws RemoteException   {      super();      updateWeatherConditions();      t = new Thread( this );      // create GregorianCalendar with Eastern Standard Time      c = new GregorianCalendar( TimeZone.getTimeZone( "EST" ) );      // Get hour, minute and second      int h = c.get( Calendar.HOUR_OF_DAY );      int m = c.get( Calendar.MINUTE );      int s = c.get( Calendar.SECOND );      setDelay( h, m, s );      // create and start thread that sleeps for the delay time      delay = new TimeDelay();      delay.start();   }   private void setDelay( int h, int m, int s )   {      // calculate difference between current time and      // 11 AM or 11 PM (the times to update weather)      dh = ( h >= 11 ? 22 : 10 ) - h;      dm = 59 - m;      ds = 60 - s;   }   private class TimeDelay extends Thread {      public void run()      {                                                                try {            // sleep for the amount of time between the server            // startup and either 11 AM or 11 PM            Thread.sleep( dh * 60 * 60 * 1000 + dm * 60 * 1000 +                          ds * 1000 );            t.start();   // start 12 Hour cycle         }         catch ( InterruptedException e ) {            System.err.println( "Exception in TimeDelay." );         }      }   }   // get weather information from NWS   private void updateWeatherConditions()      throws RemoteException   {      try {                  System.err.println(            "Updating weather information..." );         // Traveler's Forecast Web Page         URL url = new URL(            "http://iwin.nws.noaa.gov/iwin/us/traveler.html" );         BufferedReader in =            new BufferedReader(               new InputStreamReader( url.openStream() ) );                  String separator = "



";         // locate first horizontal line on Web page          while ( !in.readLine().startsWith( separator ) )            ;    // do nothing         // s1 is the day format and s2 is the night format         String s1 =            "CITY            WEA     HI/LO   WEA     HI/LO";         String s2 =            "CITY            WEA     LO/HI   WEA     LO/HI";         String inputLine = "";         // locate header that begins weather information         do {            inputLine = in.readLine();         } while ( !inputLine.equals( s1 ) &&                   !inputLine.equals( s2 ) );         Vector cityVector = new Vector();         inputLine = in.readLine();  // get first city's info         while ( !inputLine.equals( "" ) ) {                        // create WeatherInfo object for city            WeatherInfo w = new WeatherInfo(               inputLine.substring( 0, 16 ),               inputLine.substring( 16, 22 ),               inputLine.substring( 23, 29 ) );            cityVector.addElement( w ); // add to Vector            inputLine = in.readLine();  // get next city's info         }         // create array to return to client         weatherInformation =             new WeatherInfo[ cityVector.size() ];         for ( int i = 0; i < weatherInformation.length; i++ )                       weatherInformation[ i ] =               ( WeatherInfo ) cityVector.elementAt( i );          System.err.println( "Finished Processing Data." );         in.close();  // close connection to NWS server        }      catch( java.net.ConnectException ce ) {         System.err.println( "Connection failed." );         System.exit( 1 );      }      catch( Exception e ) {         e.printStackTrace();         System.exit( 1 );      }   }   // implementation for TemperatureServer interface method   public WeatherInfo[] getWeatherInfo()   {      return weatherInformation;   }   public void run()   {      try {         while ( true ) {            updateWeatherConditions();            // sleep for 12 Hours            Thread.sleep( 12 * 60 * 60 * 1000 );         }      }      catch ( InterruptedException e ) {         e.printStackTrace();      }      catch ( RemoteException re ) {         System.err.println( "RemoteException in run." );      }   }   public static void main( String args[] ) throws Exception   {           System.err.println(         "Initializing server: please wait." );      // create server object      TemperatureServerImpl temp =          new TemperatureServerImpl();      // bind TemperatureServerImpl object to the rmiregistry      String serverObjectName = "//localhost/TempServer";      Naming.rebind( serverObjectName, temp );      System.err.println(         "The Temperature Server is up and running." );   }}/************************************************************************** * (C) Copyright 1999 by Deitel & Associates, Inc. and Prentice Hall.     * * All Rights Reserved.                                                   * *                                                                        * * DISCLAIMER: The authors and publisher of this book have used their     * * best efforts in preparing the book. These efforts include the          * * development, research, and testing of the theories and programs        * * to determine their effectiveness. The authors and publisher make       * * no warranty of any kind, expressed or implied, with regard to these    * * programs or to the documentation contained in these books. The authors * * and publisher shall not be liable in any event for incidental or       * * consequential damages in connection with, or arising out of, the       * * furnishing, performance, or use of these programs.                     * *************************************************************************/