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, CompositeValueModel composite) {
026            this(-1, null, typeUri, roleModel1, roleModel2, null, composite);
027        }
028    
029        public AssociationModel(long id) {
030            super(id);
031        }
032    
033        public AssociationModel(long id, String uri, String typeUri, RoleModel roleModel1, RoleModel roleModel2) {
034            this(id, uri, typeUri, roleModel1, roleModel2, null, null);
035        }
036    
037        public AssociationModel(long id, String uri, String typeUri, RoleModel roleModel1, RoleModel roleModel2,
038                                                                         SimpleValue value, CompositeValueModel composite) {
039            super(id, uri, typeUri, value, composite);
040            this.roleModel1 = roleModel1;
041            this.roleModel2 = roleModel2;
042        }
043    
044        public AssociationModel(AssociationModel model) {
045            super(model);
046            this.roleModel1 = model.getRoleModel1();
047            this.roleModel2 = model.getRoleModel2();
048        }
049    
050        public AssociationModel(JSONObject assocModel) {
051            super(assocModel);
052            try {
053                if (assocModel.has("role_1")) {
054                    this.roleModel1 = parseRole(assocModel.getJSONObject("role_1"));
055                }
056                if (assocModel.has("role_2")) {
057                    this.roleModel2 = parseRole(assocModel.getJSONObject("role_2"));
058                }
059            } catch (Exception e) {
060                throw new RuntimeException("Parsing AssociationModel failed (JSONObject=" + assocModel + ")", e);
061            }
062        }
063    
064        // -------------------------------------------------------------------------------------------------- Public Methods
065    
066        public RoleModel getRoleModel1() {
067            return roleModel1;
068        }
069    
070        public RoleModel getRoleModel2() {
071            return roleModel2;
072        }
073    
074        // --- Convenience Methods ---
075    
076        public RoleModel getRoleModel(String roleTypeUri) {
077            boolean rm1 = roleModel1.getRoleTypeUri().equals(roleTypeUri);
078            boolean rm2 = roleModel2.getRoleTypeUri().equals(roleTypeUri);
079            if (rm1 && rm2) {
080                throw new RuntimeException("Ambiguous getRoleModel() call: both players occupy role \"" +
081                    roleTypeUri + "\" in association (" + this + ")");
082            } else if (rm1) {
083                return roleModel1;
084            } else if (rm2) {
085                return roleModel2;
086            }
087            return null;
088        }
089    
090        public long getOtherPlayerId(long id) {
091            long id1 = roleModel1.getPlayerId();
092            long id2 = roleModel2.getPlayerId();
093            if (id1 == id) {
094                return id2;
095            } else if (id2 == id) {
096                return id1;
097            } else {
098                throw new IllegalArgumentException("ID " + id + " doesn't refer to a player in " + this);
099            }
100        }
101    
102        public boolean hasSameRoleTypeUris() {
103            return roleModel1.getRoleTypeUri().equals(roleModel2.getRoleTypeUri());
104        }
105    
106    
107    
108        // === Implementation of the abstract methods ===
109    
110        @Override
111        public RoleModel createRoleModel(String roleTypeUri) {
112            return new AssociationRoleModel(getId(), roleTypeUri);
113        }
114    
115    
116    
117        // === Serialization ===
118    
119        public JSONObject toJSON() {
120            try {
121                JSONObject o = super.toJSON();
122                o.put("role_1", roleModel1.toJSON());
123                o.put("role_2", roleModel2.toJSON());
124                return o;
125            } catch (Exception e) {
126                throw new RuntimeException("Serialization failed (" + this + ")", e);
127            }
128        }
129    
130    
131    
132        // === Java API ===
133    
134        @Override
135        public AssociationModel clone() {
136            try {
137                AssociationModel model = (AssociationModel) super.clone();
138                model.roleModel1 = roleModel1.clone();
139                model.roleModel2 = roleModel2.clone();
140                return model;
141            } catch (Exception e) {
142                throw new RuntimeException("Cloning an AssociationModel failed", e);
143            }
144        }
145    
146        @Override
147        public String toString() {
148            return "association (" + super.toString() + "," + roleModel1 + "," + roleModel2 + ")";
149        }
150    
151    
152    
153        // ------------------------------------------------------------------------------------------------- Private Methods
154    
155        private RoleModel parseRole(JSONObject roleModel) {
156            if (roleModel.has("topic_id") || roleModel.has("topic_uri")) {
157                return new TopicRoleModel(roleModel);
158            } else if (roleModel.has("assoc_id")) {
159                return new AssociationRoleModel(roleModel);
160            } else {
161                throw new RuntimeException("Parsing TopicRoleModel/AssociationRoleModel failed " +
162                    "(JSONObject=" + roleModel + ")");
163            }
164        }
165    }