001package de.deepamehta.core.impl;
002
003import de.deepamehta.core.AssociationDefinition;
004import de.deepamehta.core.DeepaMehtaObject;
005import de.deepamehta.core.RelatedTopic;
006import de.deepamehta.core.model.ChildTopicsModel;
007import de.deepamehta.core.model.DeepaMehtaObjectModel;
008import de.deepamehta.core.model.RelatedTopicModel;
009import de.deepamehta.core.model.SimpleValue;
010
011import org.codehaus.jettison.json.JSONObject;
012
013import java.util.List;
014
015
016
017/**
018 * A DeepaMehta object model that is attached to the DB.
019 *
020 * Method name conventions and semantics:
021 *  - getXX()           Reads from memory (model).
022 *  - setXX(arg)        Writes to memory (model) and DB. Elementary operation.
023 *  - updateXX(arg)     Compares arg with current value (model) and calls setXX() method(s) if required.
024 *                      Can be called with arg=null which indicates no update is requested.
025 *                      Typically returns nothing.
026 *  - fetchXX()         Fetches value from DB.              ### FIXDOC
027 *  - storeXX()         Stores current value (model) to DB. ### FIXDOC
028 */
029abstract class DeepaMehtaObjectImpl implements DeepaMehtaObject {
030
031    // ---------------------------------------------------------------------------------------------- Instance Variables
032
033    DeepaMehtaObjectModelImpl model;    // underlying model
034
035    PersistenceLayer pl;
036    ModelFactoryImpl mf;
037
038    // ---------------------------------------------------------------------------------------------------- Constructors
039
040    DeepaMehtaObjectImpl(DeepaMehtaObjectModelImpl model, PersistenceLayer pl) {
041        this.model = model;
042        this.pl = pl;
043        this.mf = pl.mf;
044    }
045
046    // -------------------------------------------------------------------------------------------------- Public Methods
047
048
049
050    // ***************************************
051    // *** DeepaMehtaObject Implementation ***
052    // ***************************************
053
054
055
056    // === Model ===
057
058    // --- ID ---
059
060    @Override
061    public long getId() {
062        return model.getId();
063    }
064
065    // --- URI ---
066
067    @Override
068    public String getUri() {
069        return model.getUri();
070    }
071
072    @Override
073    public void setUri(String uri) {
074        model.updateUri(uri);
075    }
076
077    // --- Type URI ---
078
079    @Override
080    public String getTypeUri() {
081        return model.getTypeUri();
082    }
083
084    @Override
085    public void setTypeUri(String typeUri) {
086        model.updateTypeUri(typeUri);
087    }
088
089    // --- Simple Value ---
090
091    @Override
092    public SimpleValue getSimpleValue() {
093        return model.getSimpleValue();
094    }
095
096    // ---
097
098    @Override
099    public void setSimpleValue(String value) {
100        setSimpleValue(new SimpleValue(value));
101    }
102
103    @Override
104    public void setSimpleValue(int value) {
105        setSimpleValue(new SimpleValue(value));
106    }
107
108    @Override
109    public void setSimpleValue(long value) {
110        setSimpleValue(new SimpleValue(value));
111    }
112
113    @Override
114    public void setSimpleValue(boolean value) {
115        setSimpleValue(new SimpleValue(value));
116    }
117
118    @Override
119    public void setSimpleValue(SimpleValue value) {
120        model.updateSimpleValue(value);
121    }
122
123    // --- Child Topics ---
124
125    @Override
126    public ChildTopicsImpl getChildTopics() {
127        return new ChildTopicsImpl(model.childTopics, model, pl);
128    }
129
130    // ### FIXME: no UPDATE directive for *this* object is added. No UPDATE event for *this* object is fired.
131    // We should call the abstract updateChildTopics() instead.
132    @Override
133    public void setChildTopics(ChildTopicsModel childTopics) {
134        try {
135            model._updateChildTopics(childTopics);
136        } catch (Exception e) {
137            throw new RuntimeException("Setting the child topics failed (" + childTopics + ")", e);
138        }
139    }
140
141    // ---
142
143    @Override
144    public DeepaMehtaObject loadChildTopics() {
145        model.loadChildTopics();
146        return this;
147    }
148
149    @Override
150    public DeepaMehtaObject loadChildTopics(String assocDefUri) {
151        model.loadChildTopics(assocDefUri);
152        return this;
153    }
154
155    // ---
156
157    // Note: getType() remains abstract
158
159    @Override
160    public DeepaMehtaObjectModelImpl getModel() {
161        return model;
162    }
163
164
165
166    // === Updating ===
167
168    @Override
169    public final void update(DeepaMehtaObjectModel newModel) {
170        model.update(newModel);
171    }
172
173    // ---
174
175    // ### FIXME: no UPDATE directive for *this* object is added. No UPDATE event for *this* object is fired.
176    // Directives/events is handled only in the high-level update() method.
177    // Here however we need to call the low-level updateChildTopics() method in order to pass an arbitrary assoc def.
178    @Override
179    public void updateChildTopic(RelatedTopicModel newChildTopic, AssociationDefinition assocDef) {
180        model.updateChildTopics(newChildTopic, null, assocDef.getModel());      // newChildTopics=null
181    }
182
183    // ### FIXME: no UPDATE directive for *this* object is added. No UPDATE event for *this* object is fired.
184    // Directives/events is handled only in the high-level update() method.
185    // Here however we need to call the low-level updateChildTopics() method in order to pass an arbitrary assoc def.
186    @Override
187    public void updateChildTopics(List<? extends RelatedTopicModel> newChildTopics, AssociationDefinition assocDef) {
188        model.updateChildTopics(null, newChildTopics, assocDef.getModel());     // newChildTopic=null
189    }
190
191
192
193    // === Deletion ===
194
195    @Override
196    public final void delete() {
197        model.delete();
198    }
199
200
201
202    // === Traversal ===
203
204    // --- Topic Retrieval ---
205
206    @Override
207    public RelatedTopic getRelatedTopic(String assocTypeUri, String myRoleTypeUri, String othersRoleTypeUri,
208                                                                                   String othersTopicTypeUri) {
209        RelatedTopicModelImpl topic = model.getRelatedTopic(assocTypeUri, myRoleTypeUri, othersRoleTypeUri,
210            othersTopicTypeUri);
211        return topic != null ? pl.<RelatedTopic>checkReadAccessAndInstantiate(topic) : null;
212    }
213
214    @Override
215    public List<RelatedTopic> getRelatedTopics(String assocTypeUri) {
216        return getRelatedTopics(assocTypeUri, null, null, null);
217    }
218
219    @Override
220    public List<RelatedTopic> getRelatedTopics(String assocTypeUri, String myRoleTypeUri, String othersRoleTypeUri,
221                                                                                          String othersTopicTypeUri) {
222        List<RelatedTopicModelImpl> topics = model.getRelatedTopics(assocTypeUri, myRoleTypeUri, othersRoleTypeUri,
223            othersTopicTypeUri);
224        return pl.checkReadAccessAndInstantiate(topics);
225    }
226
227    // Note: this method is implemented in the subclasses (this is an abstract class):
228    //     getRelatedTopics(List assocTypeUris, ...)
229
230    // --- Association Retrieval ---
231
232    // Note: these methods are implemented in the subclasses (this is an abstract class):
233    //     getAssociation(...)
234    //     getAssociations()
235
236
237
238    // === Properties ===
239
240    @Override
241    public Object getProperty(String propUri) {
242        return pl.fetchProperty(getId(), propUri);
243    }
244
245    @Override
246    public boolean hasProperty(String propUri) {
247        return pl.hasProperty(getId(), propUri);
248    }
249
250    // Note: these methods are implemented in the subclasses:
251    //     setProperty(...)
252    //     removeProperty(...)
253
254
255
256    // === Misc ===
257
258    @Override
259    public Object getDatabaseVendorObject() {
260        return pl.getDatabaseVendorObject(getId());
261    }
262
263
264
265    // **********************************
266    // *** JSONEnabled Implementation ***
267    // **********************************
268
269
270
271    @Override
272    public JSONObject toJSON() {
273        return model.toJSON();
274    }
275
276
277
278    // ****************
279    // *** Java API ***
280    // ****************
281
282
283
284    @Override
285    public boolean equals(Object o) {
286        return ((DeepaMehtaObjectImpl) o).model.equals(model);
287    }
288
289    @Override
290    public int hashCode() {
291        return model.hashCode();
292    }
293
294    @Override
295    public String toString() {
296        return model.toString();
297    }
298
299
300
301    // ----------------------------------------------------------------------------------------- Package Private Methods
302
303    final String className() {
304        return model.className();
305    }
306}