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