001    package de.deepamehta.core.model;
002    
003    import org.codehaus.jettison.json.JSONObject;
004    
005    
006    
007    /**
008     * Collection of the data that makes up an {@link Association}.
009     *
010     * @author <a href="mailto:jri@deepamehta.de">Jörg Richter</a>
011     */
012    public class AssociationModel extends DeepaMehtaObjectModel {
013    
014        // ---------------------------------------------------------------------------------------------- Instance Variables
015    
016        private RoleModel roleModel1;   // may be null in models used for an update operation
017        private RoleModel roleModel2;   // may be null in models used for an update operation
018    
019        // ---------------------------------------------------------------------------------------------------- Constructors
020    
021        public AssociationModel(String typeUri, RoleModel roleModel1, RoleModel roleModel2) {
022            this(typeUri, roleModel1, roleModel2, null);
023        }
024    
025        public AssociationModel(String typeUri, RoleModel roleModel1, RoleModel roleModel2, ChildTopicsModel childTopics) {
026            this(-1, null, typeUri, roleModel1, roleModel2, null, childTopics);
027        }
028    
029        public AssociationModel() {
030            super(-1);
031        }
032    
033        public AssociationModel(long id) {
034            super(id);
035        }
036    
037        public AssociationModel(ChildTopicsModel childTopics) {
038            super(childTopics);
039        }
040    
041        public AssociationModel(long id, String uri, String typeUri, RoleModel roleModel1, RoleModel roleModel2) {
042            this(id, uri, typeUri, roleModel1, roleModel2, null, null);
043        }
044    
045        public AssociationModel(long id, String uri, String typeUri, RoleModel roleModel1, RoleModel roleModel2,
046                                                                     SimpleValue value, ChildTopicsModel childTopics) {
047            super(id, uri, typeUri, value, childTopics);
048            this.roleModel1 = roleModel1;
049            this.roleModel2 = roleModel2;
050        }
051    
052        public AssociationModel(AssociationModel assoc) {
053            super(assoc);
054            this.roleModel1 = assoc.getRoleModel1();
055            this.roleModel2 = assoc.getRoleModel2();
056        }
057    
058        public AssociationModel(JSONObject assoc) {
059            super(assoc);
060            try {
061                if (assoc.has("role_1")) {
062                    this.roleModel1 = parseRole(assoc.getJSONObject("role_1"));
063                }
064                if (assoc.has("role_2")) {
065                    this.roleModel2 = parseRole(assoc.getJSONObject("role_2"));
066                }
067            } catch (Exception e) {
068                throw new RuntimeException("Parsing AssociationModel failed (JSONObject=" + assoc + ")", e);
069            }
070        }
071    
072        // -------------------------------------------------------------------------------------------------- Public Methods
073    
074        public RoleModel getRoleModel1() {
075            return roleModel1;
076        }
077    
078        public RoleModel getRoleModel2() {
079            return roleModel2;
080        }
081    
082        // ---
083    
084        public void setRoleModel1(RoleModel roleModel1) {
085            this.roleModel1 = roleModel1;
086        }
087    
088        public void setRoleModel2(RoleModel roleModel2) {
089            this.roleModel2 = roleModel2;
090        }
091    
092        // --- Convenience Methods ---
093    
094        public RoleModel getRoleModel(String roleTypeUri) {
095            boolean rm1 = roleModel1.getRoleTypeUri().equals(roleTypeUri);
096            boolean rm2 = roleModel2.getRoleTypeUri().equals(roleTypeUri);
097            if (rm1 && rm2) {
098                throw new RuntimeException("Ambiguous getRoleModel() call: both players occupy role \"" +
099                    roleTypeUri + "\" in association (" + this + ")");
100            } else if (rm1) {
101                return roleModel1;
102            } else if (rm2) {
103                return roleModel2;
104            }
105            return null;
106        }
107    
108        public long getOtherPlayerId(long id) {
109            long id1 = roleModel1.getPlayerId();
110            long id2 = roleModel2.getPlayerId();
111            if (id1 == id) {
112                return id2;
113            } else if (id2 == id) {
114                return id1;
115            } else {
116                throw new IllegalArgumentException("ID " + id + " doesn't refer to a player in " + this);
117            }
118        }
119    
120        public boolean hasSameRoleTypeUris() {
121            return roleModel1.getRoleTypeUri().equals(roleModel2.getRoleTypeUri());
122        }
123    
124    
125    
126        // === Implementation of the abstract methods ===
127    
128        @Override
129        public RoleModel createRoleModel(String roleTypeUri) {
130            return new AssociationRoleModel(getId(), roleTypeUri);
131        }
132    
133    
134    
135        // === Serialization ===
136    
137        public JSONObject toJSON() {
138            try {
139                JSONObject o = super.toJSON();
140                o.put("role_1", roleModel1.toJSON());
141                o.put("role_2", roleModel2.toJSON());
142                return o;
143            } catch (Exception e) {
144                throw new RuntimeException("Serialization failed (" + this + ")", e);
145            }
146        }
147    
148    
149    
150        // === Java API ===
151    
152        @Override
153        public AssociationModel clone() {
154            try {
155                AssociationModel model = (AssociationModel) super.clone();
156                model.roleModel1 = roleModel1.clone();
157                model.roleModel2 = roleModel2.clone();
158                return model;
159            } catch (Exception e) {
160                throw new RuntimeException("Cloning an AssociationModel failed", e);
161            }
162        }
163    
164        @Override
165        public String toString() {
166            return "association (" + super.toString() + ", " + roleModel1 + ", " + roleModel2 + ")";
167        }
168    
169    
170    
171        // ------------------------------------------------------------------------------------------------- Private Methods
172    
173        private RoleModel parseRole(JSONObject roleModel) {
174            if (roleModel.has("topic_id") || roleModel.has("topic_uri")) {
175                return new TopicRoleModel(roleModel);
176            } else if (roleModel.has("assoc_id")) {
177                return new AssociationRoleModel(roleModel);
178            } else {
179                throw new RuntimeException("Parsing TopicRoleModel/AssociationRoleModel failed " +
180                    "(JSONObject=" + roleModel + ")");
181            }
182        }
183    }