001    package de.deepamehta.plugins.geomaps.model;
002    
003    import de.deepamehta.core.JSONEnabled;
004    import de.deepamehta.core.RelatedTopic;
005    import de.deepamehta.core.Topic;
006    import de.deepamehta.core.model.TopicModel;
007    import de.deepamehta.core.service.DeepaMehtaService;
008    import de.deepamehta.core.service.ResultList;
009    import de.deepamehta.core.util.DeepaMehtaUtils;
010    
011    import org.codehaus.jettison.json.JSONObject;
012    
013    import java.util.HashMap;
014    import java.util.Iterator;
015    import java.util.Map;
016    import 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    public class Geomap implements Iterable<TopicModel>, JSONEnabled {
028    
029        // ---------------------------------------------------------------------------------------------- Instance Variables
030    
031        protected Topic geomapTopic;
032        protected Map<Long, TopicModel> geoCoords = new HashMap();
033    
034        protected DeepaMehtaService dms;
035    
036        private Logger logger = Logger.getLogger(getClass().getName());
037    
038        // ---------------------------------------------------------------------------------------------------- Constructors
039    
040        /**
041         * Loads a topicmap from the DB.
042         */
043        public Geomap(long geomapId, DeepaMehtaService dms) {
044            logger.info("Loading geomap " + geomapId);
045            // Note: a Geomap is not a DeepaMehtaObject. So the JerseyResponseFilter's automatic
046            // child topic loading is not applied. We must load the child topics manually here.
047            this.geomapTopic = dms.getTopic(geomapId).loadChildTopics();
048            this.dms = dms;
049            //
050            fetchGeoCoordinates();
051        }
052    
053        // -------------------------------------------------------------------------------------------------- Public Methods
054    
055        public long getId() {
056            return geomapTopic.getId();
057        }
058    
059        // ### TODO: needed?
060        public boolean containsTopic(long geoCoordId) {
061            return geoCoords.get(geoCoordId) != null;
062        }
063    
064        // ---
065    
066        @Override
067        public JSONObject toJSON() {
068            try {
069                JSONObject topicmap = new JSONObject();
070                topicmap.put("info", geomapTopic.toJSON());
071                topicmap.put("topics", DeepaMehtaUtils.objectsToJSON(geoCoords.values()));
072                return topicmap;
073            } catch (Exception e) {
074                throw new RuntimeException("Serialization failed (" + this + ")", e);
075            }
076        }
077    
078        @Override
079        public Iterator<TopicModel> iterator() {
080            return geoCoords.values().iterator();
081        }
082    
083        @Override
084        public String toString() {
085            return "geomap " + getId();
086        }
087    
088        // ------------------------------------------------------------------------------------------------- Private Methods
089    
090        private void fetchGeoCoordinates() {
091            for (Topic geoCoord : fetchGeoCoordinates(geomapTopic)) {
092                geoCoords.put(geoCoord.getId(), geoCoord.getModel());
093            }
094        }
095    
096        private ResultList<RelatedTopic> fetchGeoCoordinates(Topic geomapTopic) {
097            return geomapTopic.getRelatedTopics("dm4.geomaps.geotopic_mapcontext", "dm4.core.default",
098                "dm4.topicmaps.topicmap_topic", "dm4.geomaps.geo_coordinate", 0).loadChildTopics();     // maxResultSize=0
099        }
100    }