001package de.deepamehta.core.model;
002
003import 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 */
012public 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}