001    package de.deepamehta.core.model;
002    
003    import org.codehaus.jettison.json.JSONArray;
004    import org.codehaus.jettison.json.JSONObject;
005    
006    import java.util.HashMap;
007    import java.util.List;
008    import java.util.Map;
009    
010    
011    
012    /**
013     * The role a topic plays in an association.
014     * <p>
015     * A TopicRoleModel object is a pair of a topic reference and a role type reference.
016     * The topic is refered to either by its ID or URI.
017     * The role type is refered to by its URI.
018     * <p>
019     * Assertion: both, the topic reference and the role type reference are set.
020     * <p>
021     * In the database a role type is represented by a topic of type "dm4.core.role_type".
022     */
023    public class TopicRoleModel extends RoleModel {
024    
025        // ---------------------------------------------------------------------------------------------- Instance Variables
026    
027        private String topicUri;
028        private boolean topicIdentifiedByUri;
029    
030        // ---------------------------------------------------------------------------------------------------- Constructors
031    
032        public TopicRoleModel(long topicId, String roleTypeUri) {
033            super(topicId, roleTypeUri);
034            this.topicUri = null;
035            this.topicIdentifiedByUri = false;
036        }
037    
038        public TopicRoleModel(String topicUri, String roleTypeUri) {
039            super(-1, roleTypeUri);
040            this.topicUri = topicUri;
041            this.topicIdentifiedByUri = true;
042        }
043    
044        public TopicRoleModel(JSONObject topicRoleModel) {
045            try {
046                this.playerId = topicRoleModel.optLong("topic_id", -1);
047                this.topicUri = topicRoleModel.optString("topic_uri", null);
048                this.roleTypeUri = topicRoleModel.getString("role_type_uri");
049                this.topicIdentifiedByUri = topicUri != null;
050                //
051                if (playerId == -1 && topicUri == null) {
052                    throw new IllegalArgumentException("Neiter \"topic_id\" nor \"topic_uri\" is set");
053                }
054                if (playerId != -1 && topicUri != null) {
055                    throw new IllegalArgumentException("\"topic_id\" and \"topic_uri\" must not be set at the same time");
056                }
057            } catch (Exception e) {
058                throw new RuntimeException("Parsing TopicRoleModel failed (JSONObject=" + topicRoleModel + ")", e);
059            }
060        }
061    
062        // -------------------------------------------------------------------------------------------------- Public Methods
063    
064        @Override
065        public long getPlayerId() {
066            if (topicIdentifiedByUri) {
067                throw new IllegalStateException("The topic is not identified by ID but by URI (" + this + ")");
068            }
069            return super.getPlayerId();
070        }
071    
072        public String getTopicUri() {
073            if (!topicIdentifiedByUri) {
074                throw new IllegalStateException("The topic is not identified by URI but by ID (" + this + ")");
075            }
076            return topicUri;
077        }
078    
079        public boolean topicIdentifiedByUri() {
080            return topicIdentifiedByUri;
081        }
082    
083        // === Implementation of abstract RoleModel methods ===
084    
085        @Override
086        public boolean refsSameObject(RoleModel model) {
087            if (model instanceof TopicRoleModel) {
088                TopicRoleModel topicRole = (TopicRoleModel) model;
089                if (topicRole.topicIdentifiedByUri == topicIdentifiedByUri) {
090                    if (topicIdentifiedByUri) {
091                        return topicRole.topicUri.equals(topicUri);
092                    } else {
093                        return topicRole.playerId == playerId;
094                    }
095                }
096            }
097            return false;
098        }
099    
100        @Override
101        public JSONObject toJSON() {
102            try {
103                JSONObject o = new JSONObject();
104                if (topicIdentifiedByUri) {
105                    o.put("topic_uri", topicUri);
106                } else {
107                    o.put("topic_id", playerId);
108                }
109                o.put("role_type_uri", roleTypeUri);
110                return o;
111            } catch (Exception e) {
112                throw new RuntimeException("Serialization failed (" + this + ")", e);
113            }
114        }
115    
116        // === Java API ===
117    
118        @Override
119        public String toString() {
120            String player = topicIdentifiedByUri ? "topicUri=\"" + topicUri + "\"" : "playerId=" + playerId;
121            return "\n        topic role (roleTypeUri=\"" + roleTypeUri + "\", " + player + ")";
122        }
123    }