001package de.deepamehta.core.impl; 002 003import de.deepamehta.core.AssociationDefinition; 004import de.deepamehta.core.DeepaMehtaObject; 005import de.deepamehta.core.DeepaMehtaType; 006import de.deepamehta.core.RelatedTopic; 007import de.deepamehta.core.model.ChildTopicsModel; 008import de.deepamehta.core.model.DeepaMehtaObjectModel; 009import de.deepamehta.core.model.RelatedTopicModel; 010import de.deepamehta.core.model.SimpleValue; 011 012import org.codehaus.jettison.json.JSONObject; 013 014import java.util.List; 015 016 017 018/** 019 * A DeepaMehta 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 DeepaMehtaObjectImpl implements DeepaMehtaObject { 031 032 // ---------------------------------------------------------------------------------------------- Instance Variables 033 034 DeepaMehtaObjectModelImpl model; // underlying model 035 036 PersistenceLayer pl; 037 ModelFactoryImpl mf; 038 039 // ---------------------------------------------------------------------------------------------------- Constructors 040 041 DeepaMehtaObjectImpl(DeepaMehtaObjectModelImpl 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 // *** DeepaMehtaObject 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); 122 } 123 124 // --- Child Topics --- 125 126 @Override 127 public final ChildTopicsImpl getChildTopics() { 128 return new ChildTopicsImpl(model.childTopics, model, pl); 129 } 130 131 // ### FIXME: no UPDATE directive for *this* object is added. No UPDATE event for *this* object is fired. 132 // We should call the abstract updateWithChildTopics() instead. 133 @Override 134 public final void setChildTopics(ChildTopicsModel childTopics) { 135 try { 136 model._updateChildTopics((ChildTopicsModelImpl) childTopics); 137 } catch (Exception e) { 138 throw new RuntimeException("Setting the child topics failed (" + childTopics + ")", e); 139 } 140 } 141 142 // --- 143 144 @Override 145 public DeepaMehtaObject loadChildTopics() { 146 model.loadChildTopics(); 147 return this; 148 } 149 150 @Override 151 public DeepaMehtaObject loadChildTopics(String assocDefUri) { 152 model.loadChildTopics(assocDefUri); 153 return this; 154 } 155 156 // --- 157 158 @Override 159 public final DeepaMehtaType getType() { 160 return model.getType().instantiate(); 161 } 162 163 @Override 164 public DeepaMehtaObjectModelImpl getModel() { 165 return model; 166 } 167 168 169 170 // === Updating === 171 172 @Override 173 public final void update(DeepaMehtaObjectModel updateModel) { 174 model.update((DeepaMehtaObjectModelImpl) updateModel); // ### FIXME: call through pl for access control 175 } 176 177 // --- 178 179 // ### FIXME: no UPDATE directive for *this* object is added. No UPDATE event for *this* object is fired. 180 // Directives/events is handled only in the high-level update() method. 181 // Here however we need to call the low-level updateChildTopics() method in order to pass an arbitrary assoc def. 182 @Override 183 public final void updateChildTopic(RelatedTopicModel newChildTopic, AssociationDefinition assocDef) { 184 model.updateChildTopics((RelatedTopicModelImpl) newChildTopic, null, assocDef.getModel()); 185 // newChildTopics=null 186 } 187 188 // ### FIXME: no UPDATE directive for *this* object is added. No UPDATE event for *this* object is fired. 189 // Directives/events is handled only in the high-level update() method. 190 // Here however we need to call the low-level updateChildTopics() method in order to pass an arbitrary assoc def. 191 @Override 192 public final void updateChildTopics(List<? extends RelatedTopicModel> newChildTopics, 193 AssociationDefinition assocDef) { 194 model.updateChildTopics(null, (List<RelatedTopicModelImpl>) newChildTopics, assocDef.getModel()); 195 // newChildTopic=null 196 } 197 198 199 200 // === Deletion === 201 202 @Override 203 public final void delete() { 204 model.delete(); // ### FIXME: call through pl for access control 205 } 206 207 208 209 // === Traversal === 210 211 // --- Topic Retrieval --- 212 213 @Override 214 public final RelatedTopic getRelatedTopic(String assocTypeUri, String myRoleTypeUri, 215 String othersRoleTypeUri, String othersTopicTypeUri) { 216 RelatedTopicModelImpl topic = model.getRelatedTopic(assocTypeUri, myRoleTypeUri, othersRoleTypeUri, 217 othersTopicTypeUri); 218 return topic != null ? pl.<RelatedTopic>checkReadAccessAndInstantiate(topic) : null; 219 } 220 221 @Override 222 public final List<RelatedTopic> getRelatedTopics(String assocTypeUri) { 223 return getRelatedTopics(assocTypeUri, null, null, null); 224 } 225 226 @Override 227 public final List<RelatedTopic> getRelatedTopics(String assocTypeUri, String myRoleTypeUri, 228 String othersRoleTypeUri, String othersTopicTypeUri) { 229 List<RelatedTopicModelImpl> topics = model.getRelatedTopics(assocTypeUri, myRoleTypeUri, othersRoleTypeUri, 230 othersTopicTypeUri); 231 return pl.checkReadAccessAndInstantiate(topics); 232 } 233 234 // Note: this method is implemented in the subclasses (this is an abstract class): 235 // getRelatedTopics(List assocTypeUris, ...) 236 237 // --- Association Retrieval --- 238 239 // Note: these methods are implemented in the subclasses (this is an abstract class): 240 // getAssociation(...) 241 // getAssociations() 242 243 244 245 // === Properties === 246 247 @Override 248 public final Object getProperty(String propUri) { 249 return pl.fetchProperty(getId(), propUri); 250 } 251 252 @Override 253 public final boolean hasProperty(String propUri) { 254 return pl.hasProperty(getId(), propUri); 255 } 256 257 @Override 258 public final void setProperty(String propUri, Object propValue, boolean addToIndex) { 259 model.storeProperty(propUri, propValue, addToIndex); 260 } 261 262 @Override 263 public final void removeProperty(String propUri) { 264 model.removeProperty(propUri); 265 } 266 267 268 269 // === Misc === 270 271 @Override 272 public final Object getDatabaseVendorObject() { 273 return pl.getDatabaseVendorObject(getId()); 274 } 275 276 277 278 // ********************************** 279 // *** JSONEnabled Implementation *** 280 // ********************************** 281 282 283 284 @Override 285 public final JSONObject toJSON() { 286 return model.toJSON(); 287 } 288 289 290 291 // **************** 292 // *** Java API *** 293 // **************** 294 295 296 297 @Override 298 public final boolean equals(Object o) { 299 return ((DeepaMehtaObjectImpl) o).model.equals(model); 300 } 301 302 @Override 303 public final int hashCode() { 304 return model.hashCode(); 305 } 306 307 @Override 308 public final String toString() { 309 return model.toString(); 310 } 311 312 313 314 // ----------------------------------------------------------------------------------------- Package Private Methods 315 316 final String className() { 317 return model.className(); 318 } 319}