Last revised: 07Nov01 GLGThis document is an overview of the classes in the WeatherEase Toolkit. For a complete discussion of the classes and API, see the API-docs themselves. This document presents the architectural "big picture", pointing out principal classes, features, and relationships. Related documents cover other areas, such as customization or subsetting.
Table of Contents
The WeatherEase Toolkit is an architecture and a class library for easily working with digital weather-report data. The raw data can be retrieved in real time from web-based sources, or from archived sources, or from other sources you provide. The data is then decoded and used to build Java objects using classes like Sky, Wind, Temperature, and WeatherReport. Your program then manipulates those objects in the ways you want, eventually producing whatever results you choose (text, graphics, files, databases, etc.).A demo program is provided. It shows how to use the principal toolkit classes. It also serves as an easily configurable application that can view lots of different weather reports. The demo app is also a good vehicle for testing any new classes you may write.
The raw data retrieval and decoding is encapsulated into a few easily configured and extensible classes. A ReportProvider retrieves the raw data, then a ReportBuilder turns it into a WeatherReport consisting of Sky, Wind, Temperature, and other readings. A ReportProducer connects the other components together, and can deliver reports directly to your implementation of Delivery, perhaps using a background thread running a DeliveryTask. You can also put multiple ReportProducers into a ProducerList so a DeliveryTask delivers multiple reports from a sequence of many stations.
At this time, weather forecasts are not supported in any way. A future version of the toolkit will add support for decoding forecast data and representing it with Java classes and objects. Or you could add your own support for forecasts.
There is no platform-specific code in the WeatherEase Toolkit proper. There is Mac-friendly code in the demo app's support classes, but cross-platform stubs are provided so the code can compile and run on non-Mac platforms. See Rebuilding the Toolkit for more information.These classes should work on any JVM compatible with JDK 1.1 or later. Obviously, features that use networking require an active network connection.
Tested Compatibility
This toolkit has been tested under JDK 1.1.8, JDK 1.3.0, and JDK 1.3.1.On Mac OS, this toolkit has been tested under MRJ 2.2.*, MRJ 2.1.4, and MRJ 2.0. It has been tested on a range of Mac OS versions, including 7.6.1, 8.6, 9.0, and Mac OS X (10.0 and 10.1). It has been tested on PowerPC (603e, 604e, and G4) machines.
The general architecture of the WeatherEase Toolkit is one of extensible components performing specific tasks that can be connected together in various ways. The goal was to create a smoothly extensible set of tools, rather than an all-encompassing set of provided classes.There are distinct classes and subclasses for retrieving the raw report data, for decoding the data, and for representing all the decoded data as Java objects. There are also additional classes that connect other classes together, or represent convenient collections, or perform periodic data delivery.
You can do lots of interesting things just by connecting the supplied classes together in new ways, or configuring the supplied classes differently. You may not have to create any subclasses in order to get your idea working, especially if your idea revolves around real-time delivery of weather reports.
If you need to support a new data-format, or retrieve data in new ways, however, you'll have to create subclasses. In this area, you'll find that certain capabilities have been isolated into distinct subclasses, to make it easier for you to reuse only a certain feature with minimal fuss. At first glance, this level of subclass granularity may appear to be flexibility overkill. But the first time you have to do, say, template-substitution without also using an I/O stream, you'll appreciate the factoring of the classes.
The underlying source of the raw weather report data can be anything. The data can come from continuously updated URLs on the web, from real-time weather stations, or from archived files of raw weather report data. Classes are provided that retrieve data from URLs on the web, such as the NOAA/NWS web-server that operates 24x7. It's easy to configure your programs (or the demo) to use other URLs or other schemes for retrieving raw report data.
The format of the raw weather report data can be anything. It can be binary, text, XML, or even Morse code. Obviously, I haven't provided decoders for all those formats, but I have provided decoders for the format called METAR as provided in the reports available from the NOAA/NWS server. You can define new subclasses that enhance the METAR support, decode it more robustly, or that decode entirely new formats. It's easy to configure your programs (or the demo) to use new data-format decoders.
The overall architecture of the WeatherEase Toolkit is broken up into three realms, each with a corresponding package or package-tree. The three realms are:
Building and parsing are related, but have distinct package namespaces for reasons explained below.
- Model classes -- glguerin.weather.model.*
- Builder classes -- glguerin.weather.build.*
- Parser classes -- glguerin.weather.parse.*
The Model classes represent the various readings or measurements making up a weather-report, including a WeatherReport class that holds the set of readings. There is also a Station class that holds information about a particular weather-station, and to which all WeatherReports ultimately refer. As a whole, these classes represent most of the things a typical weather-report can describe, in a manner independent of any particular underlying data-format.
I have tried to be fairly comprehensive in the model classes without necessarily being complete. For example, I have included a Visibility class, but have not given it the ability to represent runway visual range nor variable visibility. Such are the decisions one must sometimes make. Also, some aspects of some classes may not support features which do not have METAR encodings. This is simply because METAR was the principal format I was interested in decoding. So if you happen to be meteorology expert, please forgive a humble software developer who was not.
The Builder classes are the foundation for retrieving raw data and turning it into instances of the model classes. The fundamental division of responsibility here is between the ReportProvider class and the ReportBuilder class. A ReportProvider is responsible for retrieving raw data from some source and providing it in a byte-array. A ReportBuilder is responsible for decoding the raw byte-array into a WeatherReport class with whatever additional model classes (e.g. Temperature, Wind, Sky) are needed to represent the contents of the reported data. There are various subclasses of ReportProvider and ReportBuilder to aid in this process.
Another important responsibility of the builder classes is the connecting of a concrete ReportProvider with a concrete ReportBuilder, and the subsequent use of the resulting combination to produce and deliver WeatherReports for a designated Station. The principal class here is ReportProducer. You can also collect multiple ReportProducers into a ProducerList, and attach a DeliveryTask to a Thread to generate periodic delivery of reports via a single ReportProducer or a set of them in a ProducerList.
Finally, the builder classes are responsible for building Station objects using StationBuilder and its subclasses.
The Parser classes are specific implementations descended from certain builder classes. I chose to put the parser classes into their own package namespace for simple practical reasons. All parsers and decoders are ultimately descended from ReportBuilder, but there are large variations among different parser implementations. Thus, it makes sense to separate the highly variable realm of parser development from the relatively stable realm of the foundation builder classes. Among other things, this helps simplify management of several different parsers developed by different sources.
There is only a single concrete parser supplied. It parses and decodes the METAR format as supplied by the NOAA/NWS web-server at <http://weather.noaa.gov/>. Though only a single parser is provided, the implementation consists of about two dozen small classes, each of which decodes a single METAR token or a small number of related tokens. These individual decoder classes are arranged into an array, which is then walked sequentially giving each array-item a chance to examine and decode each token. This makes it very easy to create new parsers simply be creating new arrays of decoders, either adding your own new decoders, eliminating existing decoders, and so on.
Although I have named the package containing the NOAA/NWS parser "glguerin.weather.parse.nws", the classes were not created by anyone at the NWS nor are they supported, distributed, or otherwise endorsed by the NWS or NOAA.
There is a highly configurable AWT-based demo program and a bunch of isolated test programs. There are also some utility classes that the app uses, which you may find useful in writing your own apps.The Main class reads a configurable settings file and picks out a bunch of properties used to create the main Frame and the list of weather stations. Many of the classes that do the data-retrieval, parsing, and decoding are configurable using these properties. You can also configure cosmetic elements, such as the colors, fonts, and other capabilities of the main Frame and its sub-components.
- package app.weather.watch
The WatchFrame class represents the main Frame of the app. It presents a List of stations and their readings, along with a TextArea whose descriptive text changes when a List item is clicked. The contents and format of both the List-items and the TextArea description are configurable when the FlexibleListView class is chosen for presentation. A simpler FixedListView is also usable, but is more an example for development than for maximizing actual use.
Utility classes for use in WeatherEase applications.
- package app.weather.util
Test classes for testing WeatherEase classes and subclasses. The existing tests are primarily tests used during development, but you can also use them as guidelines for testing your own subclasses.
- package app.weather.test
The WeatherReport class is the nexus of all the different classes that represent readings and measurements. The Station class is also pivotal, since it's how the builder classes know what station to retrieve data for, and how recipients know where a WeatherReport came from.
- package glguerin.weather.model
The readings and measurements comprise the following classes:
- Extreme represents temperature extremes (min/max);
- Phenomenon represents all kinds of present and recent weather phenomena (snow, rain, fog, thunderstorms, etc.);
- Precipitation represents a measure of precipitation fallen over a period of time,
- Pressure represents atmospheric pressure;
- Sky represents sky-cover and cloud-layers at various altitudes;
- Temperature represents an ambient temperature and a dewpoint, and can calculate a relative-humidity;
- Visibility represents visibility as a distance;
- Wind represents wind speed, direction, and gustiness;
All the readings and measurements can return values in various units. See each of the API descriptions for details on units and conversions.
These classes form the foundation for retrieving data from various sources and using it to build various elements in the model. As noted above, the fundamental division of responsibility here is between the ReportProvider and the ReportBuilder. Both are abstract classes. Both also anchor a lineage of subclasses that provide different layers of functionality, eventually resulting in concrete implementation.
- package glguerin.weather.build
ReportProviders and ReportBuilders are typically connected together using one or more of the concrete classes: ReportProducer, ProducerList, and DeliveryTask. These are responsible for connecting together a concrete ReportProvider with a ReportBuilder and using a Station to produce and deliver reports to recipients, typically in a background Thread that runs at periodic intervals. That infrastructure is best understood by reading the API docs for the classes themselves.
The abstract StationBuilder class and its concrete TextStationBuilder implementation build Stations from arbitrary sources of underlying data. The examples and demos use text files, but you can create your own variations.
The concrete implementation of ReportProvider is URLReportProvider, which does the obvious thing: retrieve data from URLs. It does this using a pattern-substitution scheme in a template-URL, so a single URLReportProvider can actually provide data to a large number of ReportBuilders.
The concrete implementation of ReportBuilder lives in the glguerin.weather.parse package, described below.
There are a few general-purpose METAR TokenDecoder classes here. There is also a diagnostic class TellAbout that is useful when testing your own TokenDecoders, or when assembling new arrays of them.
- package glguerin.weather.parse
This package contains about two dozen individual TokenDecoder classes that decode the various supported METAR tokens. The MetarDecoding interface in this package defines a parsing context as a set of interrelated TokenDecoder arrays.
- package glguerin.weather.parse.metar
This package adds two TokenDecoder classes to all those in the glguerin.weather.parse.metar package, and uses them to at last define a concrete ReportBuilder in the NWSMetarInterpreter class. The API docs describe additional details.
- package glguerin.weather.parse.nws
This package also defines the concrete NWSStationBuilder that decodes one of the formats in which NOAA/NWS distributes lists of weather-stations and their data. The format description and the URL of the data are in the API docs for the class.
- package glguerin.util
Utility classes, including a simple linked-list, a ranked (sorted) version of the linked-list, an appender of arbitrary objects, and some text and number conversions.
To Greg's Home Page
To Greg's Software Page