The DataModel
class provides a storage for the
guide data in the MIDlet.
The class implements the singleton
pattern, and the getInstance
method provides access
to the singleton object.
public static DataModel getInstance() { if (self == null) { self = new DataModel(); } return self; }
The user's current position is stored in the singleton
object. The distanceToAttraction
method returns the
distance from the user's current position, if known, to the given
attraction. The method returns a string, so the distance can be returned
either in meters or kilometers.
private String distanceToAttraction(Attraction attraction) { final GeoCoordinate position = currentPosition; if (position == null) { return null; } double distance = position.distanceTo(attraction.getLocation()); if (distance < 1000.0) { return ((int) (distance)) + " m"; } else { String d = String.valueOf(distance % 1000).substring(0, 1); return (int) (distance / 1000) + "." + d + " km"; } }
The updateDistances
method updates
the distances from the user's position to the attractions.
private void updateDistances() { Vector attrs = attractions; if (attrs != null) { for (int i = 0; i < attrs.size(); i++) { Attraction a = (Attraction) attrs.elementAt(i); a.setDistance(distanceToAttraction(a)); } } }
When the user exits the MIDlet, the saveGuides
method stores the purchased guides to the record store.
public final void saveGuides() { try { RecordStore store = RecordStore.openRecordStore("Guides", true); if (store.getNumRecords() == 0) { store.addRecord(null, 0, 0); } byte[] data = guidesState(); store.setRecord(getRecordId(store), data, 0, data.length); store.closeRecordStore(); } catch (Exception e) { try { RecordStore.deleteRecordStore("Guides"); } catch (RecordStoreException rse) { } } } private int getRecordId(RecordStore store) throws RecordStoreException { RecordEnumeration e = store.enumerateRecords(null, null, false); try { return e.nextRecordId(); } finally { e.destroy(); } } private byte[] guidesState() { ByteArrayOutputStream bout = null; try { bout = new ByteArrayOutputStream(); DataOutputStream dout = new DataOutputStream(bout); dout.writeInt(guides.size()); for (int i = 0, size = guides.size(); i < size; i++) { ((Guide) guides.elementAt(i)).writeTo(dout); } dout.writeInt(currentGuideIndex); return bout.toByteArray(); } catch (IOException e) { } finally { try { if (bout != null) { bout.close(); } } catch (IOException e) { } } return new byte[0]; }
When the user starts the MIDlet, the loadGuides
method loads the purchased guides from the record store.
public final void loadGuides() { try { RecordStore store = RecordStore.openRecordStore("Guides", true); if (store.getNumRecords() == 0 || !loadGuides(store.getRecord(getRecordId(store)))) { guides = new Vector(); } store.closeRecordStore(); } catch (RecordStoreException e) { guides = new Vector(); } } private boolean loadGuides(byte[] record) { if (record == null) { return false; } try { DataInputStream din = new DataInputStream(new ByteArrayInputStream( record)); guides = new Vector(); int size = din.readInt(); while (size > 0) { guides.addElement(Guide.readFrom(din)); size--; } currentGuideIndex = din.readInt(); return true; } catch (IOException e) { } return false; }
The Guide
class represents a tourist guide.
The id
field uniquely identifies guides, so the equals
and hashCode
methods are overwritten
to use only the ID field.
/** * @see Object#equals(java.lang.Object) */ public final boolean equals(Object o) { if (o != null && o instanceof Guide) { return this.id.equals(((Guide) o).id); } return false; } /** * @see Object#hashCode() */ public final int hashCode() { return this.id.hashCode(); }
The writeTo
method writes the
fields that are needed to download a guide from the back-end server
to a data output stream.
public final void writeTo(DataOutputStream dout) throws IOException { dout.writeUTF(id); dout.writeUTF(purchaseTicket); dout.writeUTF(url); dout.writeUTF(imageUrl); dout.writeUTF(city); dout.writeUTF(account); }
The readFrom
method creates the
guide from the data input stream.
public static Guide readFrom(DataInputStream din) throws IOException { Guide guide = new Guide(); guide.id = din.readUTF(); guide.purchaseTicket = din.readUTF(); guide.url = din.readUTF(); guide.imageUrl = din.readUTF(); guide.city = din.readUTF(); guide.account = din.readUTF(); return guide; }
The Attraction
class represents an attraction
in a tourist guide. An attraction contains an image, description text,
and coordinates.