001package systems.dmx.geomaps.model; 002 003import systems.dmx.core.JSONEnabled; 004import systems.dmx.core.RelatedTopic; 005import systems.dmx.core.Topic; 006import systems.dmx.core.model.TopicModel; 007import systems.dmx.core.service.CoreService; 008import systems.dmx.core.util.DMXUtils; 009 010import org.codehaus.jettison.json.JSONObject; 011 012import java.util.HashMap; 013import java.util.Iterator; 014import java.util.List; 015import java.util.Map; 016import java.util.logging.Logger; 017 018 019 020/** 021 * A geomap model: a collection of Geo Coordinate topic models. 022 * <p> 023 * Features: 024 * - load from DB (by constructor). 025 * - Serialization to JSON. 026 * 027 * ### TODO: rename to GeomapViewmodel 028 */ 029public class Geomap implements Iterable<TopicModel>, JSONEnabled { 030 031 // ---------------------------------------------------------------------------------------------- Instance Variables 032 033 protected Topic geomapTopic; 034 protected Map<Long, TopicModel> geoCoords = new HashMap(); 035 036 protected CoreService dmx; 037 038 private Logger logger = Logger.getLogger(getClass().getName()); 039 040 // ---------------------------------------------------------------------------------------------------- Constructors 041 042 /** 043 * Loads a topicmap from the DB. 044 * 045 * ### TODO: pass geomap data instead of retrieving in constructor. Don't pass core service. 046 */ 047 public Geomap(long geomapId, CoreService dmx) { 048 logger.info("Loading geomap " + geomapId); 049 // Note: a Geomap is not a DMXObject. So the JerseyResponseFilter's automatic 050 // child topic loading is not applied. We must load the child topics manually here. 051 this.geomapTopic = dmx.getTopic(geomapId).loadChildTopics(); 052 this.dmx = dmx; 053 // 054 fetchGeoCoordinates(); 055 } 056 057 // -------------------------------------------------------------------------------------------------- Public Methods 058 059 public long getId() { 060 return geomapTopic.getId(); 061 } 062 063 // ### TODO: needed? 064 public boolean containsTopic(long geoCoordId) { 065 return geoCoords.get(geoCoordId) != null; 066 } 067 068 // --- 069 070 @Override 071 public JSONObject toJSON() { 072 try { 073 return new JSONObject() 074 .put("info", geomapTopic.toJSON()) 075 .put("topics", DMXUtils.toJSONArray(geoCoords.values())); 076 } catch (Exception e) { 077 throw new RuntimeException("Serialization failed", e); 078 } 079 } 080 081 @Override 082 public Iterator<TopicModel> iterator() { 083 return geoCoords.values().iterator(); 084 } 085 086 @Override 087 public String toString() { 088 return "geomap " + getId(); 089 } 090 091 // ------------------------------------------------------------------------------------------------- Private Methods 092 093 private void fetchGeoCoordinates() { 094 for (Topic geoCoord : fetchGeoCoordinates(geomapTopic)) { 095 geoCoords.put(geoCoord.getId(), geoCoord.getModel()); 096 } 097 } 098 099 private List<RelatedTopic> fetchGeoCoordinates(Topic geomapTopic) { 100 return DMXUtils.loadChildTopics(geomapTopic.getRelatedTopics("dmx.geomaps.geotopic_mapcontext", 101 "dmx.core.default", "dmx.topicmaps.topicmap_topic", "dmx.geomaps.geo_coordinate")); 102 } 103}