Measurement.java

Moving along the PhysicalMeasurement interface is the next to be implemented. The main purpose of this class is to take measurements of physical quantities of the system and store them so they can be stored by the selected DataStore. The source code for the class shows the following classes are required.

import java.util.Iterator;
import java.text.DecimalFormat;
import feynman.framework.system.PhysicalSystem;
import feynman.framework.system.PhysicalMeasurement;
import feynman.framework.simulation.Simulation;
By now several of these classes should be very familiar to you. The PhysicalMeasurement is the interface that will be implemented. The new one is the DecimalFormat class from the java.util package. The use of this class will be explained later. For now it is enough to understand that is used for formatting numerical output. Based on the physical quantities specified in the sample problem, there are several new instance variables that are part of the class definition.
public class Measurement implements PhysicalMeasurement {
	
	// --------------------------------------- instance variables.
	private Iterator i;
	private Ball b;
	private StringBuffer sb;
	private double time = 0.0;
	private double kineticEnergy = 0.0;
	private double potentialEnergy = 0.0;
	private double totalEnergy = 0.0;
	private double y = 0.0;
	private DecimalFormat csv = new DecimalFormat("000000000.00");
The class definition states we are implementing the PhysicalMeasurement interface. The Iterator and Ball instances are again there as in our other implementation classes. The next variable is the StringBuffer sb. This will be explained later in this section. There are several variables of double type used for recording various energy and position values. The DecimalFormat csv is being defined as a new format. The presence of all of the zeroes will display a double number in a format illustrated below:

Value Displayed As
3.14159265 000000003.15

There are a number of things that can be done with Formats in general. For more information on them read the Learning Java reference or consult the documentation on the Sun Java website.

The next part of the class is the typical bean getter and setter methods as illustrated below.

private void setTime(double time) {
	this.time = time;
}

...

private double getTime() {
	return this.time;
}

...
The real heart of the class is where it provides its own implementation of the take method as specified by the PhysicalMeasurement class API.
public void take(Simulation sim, PhysicalSystem ps) {

	// Retrieve the particle.
	i = ps.iterator();
	b = (Ball) i.next();
	
	// Calculate and store the time, energy and position characterisics
	// of the simulation at the time the measurement is taken.
	setTime(sim.getTime());
	setPotentialEnergy(9.8 * b.getY());
	setKineticEnergy(0.5 * b.getVy() * b.getVy());
	setTotalEnergy(getKineticEnergy() + getPotentialEnergy());
	setY(b.getY());

}
The method starts off by retrieving the Ball object from the PhysicalSystem. The measurement then takes a snapshot of the time that is maintained by the Simulation bean. It then calculates the specific energies using the nested invocation method discussed in the previous section. Lastly is catches the current position of the ball.

The next method that has to be implemented is the toString() method. This method is used by the FileDataStore to physically store the data taken during the last measurement.

public String toString() {

	sb = new StringBuffer();
	
	// Create a CSV file with the data.
	sb.append(csv.format(getTime()) + ", ");
	sb.append(csv.format(getY()) + ", ");
	sb.append(csv.format(getPotentialEnergy()) + ", ");
	sb.append(csv.format(getKineticEnergy()) + ", ");
	sb.append(csv.format(getTotalEnergy()));
	
	return sb.toString();

}
Here is where we see the StringBuffer sb instance variable being put to use. Simply put, one should use string buffers whenever you are concatinating lots of text to form a single string as in the example. The code is creating a single string that has the Comma Seperated Value (CSV) format that was seen in the data.csv file that was produced when the sample application was run. Here again we see several instances of nested invocations being performed to retrieve and manipulate data. The last step is to return the string that is created in the string buffer. Just like our class (or more appropriately, just like the string buffer), the toString() method of the string buffer is invoked and returned as a String to the class that invoked this method.

If the DbmsDataStore had been selected instead of the FileDataStore, then the toSql method would have to have been implemented. Since it is not being used, the following null implementation must be provided to comply with the PhysicalMeasurement API.

public String toSql() {

	return null;

}
If the DbmsDataStore had been chosen, then an implementation similar to the one above for the toString() method would have been done. However, instead of creating a single line in CSV format, the string would have been in the form of a SQL insert statement like the following:
insert into data values('1.00','32.00','0.00','32.00','3.50');
Currently, the Feynman 0.9 release does not have support for the DbmsDataStore in the Framework so the null implementation is the appropriate implemenation for the class and satisfies the PhysicalMeasurement API.

Previous Section | Next Section