001    package de.deepamehta.core.model;
002    
003    import org.codehaus.jettison.json.JSONObject;
004    import org.codehaus.jettison.json.JSONArray;
005    
006    import java.util.ArrayList;
007    import java.util.HashMap;
008    import java.util.List;
009    import java.util.Map;
010    import java.util.logging.Logger;
011    
012    
013    
014    /**
015     * @author <a href="mailto:jri@deepamehta.de">Jörg Richter</a>
016     */
017    public class ViewConfigurationModel {
018    
019        // ---------------------------------------------------------------------------------------------- Instance Variables
020    
021        /**
022         * Key: config topic type URI
023         */
024        private Map<String, TopicModel> viewConfig = new HashMap();
025    
026        // ---------------------------------------------------------------------------------------------------- Constructors
027    
028        public ViewConfigurationModel() {
029        }
030    
031        public ViewConfigurationModel(List<TopicModel> configTopics) {
032            for (TopicModel topic : configTopics) {
033                addConfigTopic(topic);
034            }
035        }
036    
037        /**
038         * @param   configurable    A topic type, an association type, or an association definition.
039         *                          ### FIXME: the sole JSONArray should be passed
040         */
041        public ViewConfigurationModel(JSONObject configurable) {
042            try {
043                JSONArray topics = configurable.optJSONArray("view_config_topics");
044                if (topics != null) {
045                    for (int i = 0; i < topics.length(); i++) {
046                        addConfigTopic(new TopicModel(topics.getJSONObject(i)));
047                    }
048                }
049            } catch (Exception e) {
050                throw new RuntimeException("Parsing ViewConfigurationModel failed (JSONObject=" + configurable + ")", e);
051            }
052        }
053    
054        // -------------------------------------------------------------------------------------------------- Public Methods
055    
056        public Iterable<TopicModel> getConfigTopics() {
057            return viewConfig.values();
058        }
059    
060        public void updateConfigTopic(TopicModel configTopic) {
061            String configTypeUri = configTopic.getTypeUri();
062            TopicModel confTopic = getConfigTopic(configTypeUri);
063            // error check
064            if (confTopic == null) {
065                throw new RuntimeException("There is no view configuration topic of type \"" + configTypeUri + "\"");
066            }
067            //
068            confTopic.set(configTopic);
069        }
070    
071        public TopicModel addSetting(String configTypeUri, String settingUri, Object value) {
072            // create config topic if not exists
073            boolean created = false;
074            TopicModel configTopic = getConfigTopic(configTypeUri);
075            if (configTopic == null) {
076                configTopic = new TopicModel(configTypeUri);
077                addConfigTopic(configTopic);
078                created = true;
079            }
080            // make setting
081            configTopic.getCompositeValueModel().put(settingUri, value);
082            //
083            return created ? configTopic : null;
084        }
085    
086        // ---
087    
088        /**
089         * FIXME: to be dropped.
090         * <p>
091         * Read out a view configuration setting.
092         * <p>
093         * Compare to client-side counterpart: function get_view_config() in webclient.js
094         *
095         * @param   configTypeUri   The type URI of the configuration topic, e.g. "dm4.webclient.view_config"
096         * @param   settingUri      The setting URI, e.g. "dm4.webclient.icon"
097         *
098         * @return  The setting value, or <code>null</code> if there is no such setting
099         */
100        public Object getSetting(String configTypeUri, String settingUri) {
101            TopicModel configTopic = getConfigTopic(configTypeUri);
102            if (configTopic == null) {
103                return null;
104            }
105            CompositeValueModel comp = configTopic.getCompositeValueModel();
106            return comp.has(settingUri) ? comp.getObject(settingUri) : null;
107        }
108    
109        // ---
110    
111        // ### FIXME: drop parameter, implement JSONEnabled
112        public void toJSON(JSONObject configurable) {
113            try {
114                List viewConfigTopics = new ArrayList();
115                for (TopicModel configTopic : getConfigTopics()) {
116                    viewConfigTopics.add(configTopic.toJSON());
117                }
118                configurable.put("view_config_topics", viewConfigTopics);
119            } catch (Exception e) {
120                throw new RuntimeException("Serialization failed (" + this + ")", e);
121            }
122        }
123    
124        @Override
125        public String toString() {
126            return "view configuration " + viewConfig;
127        }
128    
129        // ------------------------------------------------------------------------------------------------- Private Methods
130    
131        private TopicModel getConfigTopic(String configTypeUri) {
132            return viewConfig.get(configTypeUri);
133        }
134    
135        private void addConfigTopic(TopicModel configTopic) {
136            String configTypeUri = configTopic.getTypeUri();
137            // error check
138            if (getConfigTopic(configTypeUri) != null) {
139                throw new RuntimeException("There is already a view configuration topic of type \"" + configTypeUri + "\"");
140            }
141            //
142            viewConfig.put(configTypeUri, configTopic);
143        }
144    }