001package de.deepamehta.core.impl;
002
003import de.deepamehta.core.Association;
004import de.deepamehta.core.AssociationType;
005import de.deepamehta.core.DeepaMehtaObject;
006import de.deepamehta.core.RelatedAssociation;
007import de.deepamehta.core.RelatedTopic;
008import de.deepamehta.core.Role;
009import de.deepamehta.core.Topic;
010import de.deepamehta.core.TopicRole;
011import de.deepamehta.core.model.AssociationModel;
012import de.deepamehta.core.model.AssociationRoleModel;
013import de.deepamehta.core.model.ChildTopicsModel;
014import de.deepamehta.core.model.RelatedAssociationModel;
015import de.deepamehta.core.model.RelatedTopicModel;
016import de.deepamehta.core.model.RoleModel;
017import de.deepamehta.core.model.TopicModel;
018import de.deepamehta.core.model.TopicRoleModel;
019import de.deepamehta.core.service.Directive;
020import de.deepamehta.core.service.Directives;
021
022import java.util.List;
023
024import java.util.logging.Logger;
025
026
027
028/**
029 * An association model that is attached to the DB.
030 */
031class AssociationImpl extends DeepaMehtaObjectImpl implements Association {
032
033    // ---------------------------------------------------------------------------------------------- Instance Variables
034
035    private Logger logger = Logger.getLogger(getClass().getName());
036
037    // ---------------------------------------------------------------------------------------------------- Constructors
038
039    AssociationImpl(AssociationModelImpl model, PersistenceLayer pl) {
040        super(model, pl);
041    }
042
043    // -------------------------------------------------------------------------------------------------- Public Methods
044
045
046
047    // **********************************
048    // *** Association Implementation ***
049    // **********************************
050
051
052
053    @Override
054    public Role getRole1() {
055        return getModel().getRoleModel1().instantiate(getModel());
056    }
057
058    @Override
059    public Role getRole2() {
060        return getModel().getRoleModel2().instantiate(getModel());
061    }
062
063    // ---
064
065    @Override
066    public DeepaMehtaObject getPlayer1() {
067        return getRole1().getPlayer();
068    }
069
070    @Override
071    public DeepaMehtaObject getPlayer2() {
072        return getRole2().getPlayer();
073    }
074
075    // ---
076
077    @Override
078    public Topic getTopic(String roleTypeUri) {
079        TopicModelImpl topic = getModel().getTopic(roleTypeUri);
080        return topic != null ? new TopicImpl(topic, pl) : null;    // ### TODO: permission check?
081    }
082
083    @Override
084    public Topic getTopicByType(String topicTypeUri) {
085        TopicModelImpl topic = getModel().getTopicByType(topicTypeUri);
086        return topic != null ? new TopicImpl(topic, pl) : null;    // ### TODO: permission check?
087    }
088
089    // ---
090
091    // ### TODO: make use of model's getRole()
092    @Override
093    public Role getRole(RoleModel roleModel) {
094        if (getRole1().getModel().refsSameObject(roleModel)) {
095            return getRole1();
096        } else if (getRole2().getModel().refsSameObject(roleModel)) {
097            return getRole2();
098        }
099        throw new RuntimeException("Role is not part of association (role=" + roleModel + ", association=" + this);
100    }
101
102    @Override
103    public boolean isPlayer(TopicRoleModel roleModel) {
104        return filterRole(getRole1(), roleModel) != null || filterRole(getRole2(), roleModel) != null;
105    }
106
107    // ---
108
109    @Override
110    public void update(AssociationModel newModel) {
111        model.update(newModel);
112    }
113
114    // ---
115
116    @Override
117    public Association loadChildTopics() {
118        model.loadChildTopics();
119        return this;
120    }
121
122    @Override
123    public Association loadChildTopics(String assocDefUri) {
124        model.loadChildTopics(assocDefUri);
125        return this;
126    }
127
128    // ---
129
130    @Override
131    public AssociationType getType() {
132        return pl.getAssociationType(getTypeUri());
133    }
134
135    @Override
136    public AssociationModelImpl getModel() {
137        return (AssociationModelImpl) model;
138    }
139
140
141
142    // ***************************************
143    // *** DeepaMehtaObject Implementation ***
144    // ***************************************
145
146
147
148    // === Traversal ===
149
150    // ### TODO: move logic to model
151
152    // --- Topic Retrieval ---
153
154    @Override
155    public List<RelatedTopic> getRelatedTopics(List assocTypeUris, String myRoleTypeUri, String othersRoleTypeUri,
156                                                                                         String othersTopicTypeUri) {
157        List<RelatedTopicModelImpl> topics = pl.fetchAssociationRelatedTopics(getId(), assocTypeUris, myRoleTypeUri,
158            othersRoleTypeUri, othersTopicTypeUri);
159        return pl.checkReadAccessAndInstantiate(topics);
160    }
161
162    // --- Association Retrieval ---
163
164    @Override
165    public RelatedAssociation getRelatedAssociation(String assocTypeUri, String myRoleTypeUri,
166                                                    String othersRoleTypeUri, String othersAssocTypeUri) {
167        RelatedAssociationModelImpl assoc = pl.fetchAssociationRelatedAssociation(getId(),
168            assocTypeUri, myRoleTypeUri, othersRoleTypeUri, othersAssocTypeUri);
169        return assoc != null ? pl.<RelatedAssociation>checkReadAccessAndInstantiate(assoc) : null;
170    }
171
172    @Override
173    public List<RelatedAssociation> getRelatedAssociations(String assocTypeUri, String myRoleTypeUri,
174                                                           String othersRoleTypeUri, String othersAssocTypeUri) {
175        List<RelatedAssociationModelImpl> assocs = pl.fetchAssociationRelatedAssociations(getId(), assocTypeUri,
176            myRoleTypeUri, othersRoleTypeUri, othersAssocTypeUri);
177        return pl.checkReadAccessAndInstantiate(assocs);
178    }
179
180    // ---
181
182    @Override
183    public Association getAssociation(String assocTypeUri, String myRoleTypeUri, String othersRoleTypeUri,
184                                                                                 long othersTopicId) {
185        AssociationModelImpl assoc = pl.fetchAssociationBetweenTopicAndAssociation(assocTypeUri,
186            othersTopicId, getId(), othersRoleTypeUri, myRoleTypeUri);
187        return assoc != null ? pl.<Association>checkReadAccessAndInstantiate(assoc) : null;
188    }
189
190    @Override
191    public List<Association> getAssociations() {
192        return pl.checkReadAccessAndInstantiate(pl.fetchAssociationAssociations(getId()));
193    }
194
195
196
197    // === Properties ===
198
199    @Override
200    public void setProperty(String propUri, Object propValue, boolean addToIndex) {
201        pl.storeAssociationProperty(getId(), propUri, propValue, addToIndex);
202    }
203
204    @Override
205    public void removeProperty(String propUri) {
206        pl.removeAssociationProperty(getId(), propUri);
207    }
208
209
210
211    // ------------------------------------------------------------------------------------------------- Private Methods
212
213    // --- Helper ---
214
215    // ### TODO: move to model
216    private TopicRole filterRole(Role role, TopicRoleModel roleModel) {
217        return role instanceof TopicRole && role.getRoleTypeUri().equals(roleModel.getRoleTypeUri()) &&
218            role.getPlayerId() == roleModel.getPlayerId() ? (TopicRole) role : null;
219    }
220}