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