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 // ### FIXME: no UPDATE directive for *this* object is added. No UPDATE event for *this* object is fired. 173 // Directives/events is handled only in the high-level update() method. 174 // Here however we need to call the low-level updateChildTopics() method in order to pass an arbitrary assoc def. 175 @Override 176 public final void updateChildTopic(RelatedTopicModel newChildTopic, AssociationDefinition assocDef) { 177 model.updateChildTopics((RelatedTopicModelImpl) newChildTopic, null, assocDef.getModel()); 178 // newChildTopics=null 179 } 180 181 // ### FIXME: no UPDATE directive for *this* object is added. No UPDATE event for *this* object is fired. 182 // Directives/events is handled only in the high-level update() method. 183 // Here however we need to call the low-level updateChildTopics() method in order to pass an arbitrary assoc def. 184 @Override 185 public final void updateChildTopics(List<? extends RelatedTopicModel> newChildTopics, 186 AssociationDefinition assocDef) { 187 model.updateChildTopics(null, (List<RelatedTopicModelImpl>) newChildTopics, assocDef.getModel()); 188 // newChildTopic=null 189 } 190 191 192 193 // === Traversal === 194 195 // --- Topic Retrieval --- 196 197 @Override 198 public final RelatedTopic getRelatedTopic(String assocTypeUri, String myRoleTypeUri, 199 String othersRoleTypeUri, String othersTopicTypeUri) { 200 RelatedTopicModelImpl topic = model.getRelatedTopic(assocTypeUri, myRoleTypeUri, othersRoleTypeUri, 201 othersTopicTypeUri); 202 return topic != null ? pl.<RelatedTopic>checkReadAccessAndInstantiate(topic) : null; 203 } 204 205 @Override 206 public final List<RelatedTopic> getRelatedTopics(String assocTypeUri) { 207 return getRelatedTopics(assocTypeUri, null, null, null); 208 } 209 210 @Override 211 public final List<RelatedTopic> getRelatedTopics(String assocTypeUri, String myRoleTypeUri, 212 String othersRoleTypeUri, String othersTopicTypeUri) { 213 List<RelatedTopicModelImpl> topics = model.getRelatedTopics(assocTypeUri, myRoleTypeUri, othersRoleTypeUri, 214 othersTopicTypeUri); 215 return pl.checkReadAccessAndInstantiate(topics); 216 } 217 218 // Note: this method is implemented in the subclasses (this is an abstract class): 219 // getRelatedTopics(List assocTypeUris, ...) 220 221 // --- Association Retrieval --- 222 223 // Note: these methods are implemented in the subclasses (this is an abstract class): 224 // getAssociation(...) 225 // getAssociations() 226 227 228 229 // === Properties === 230 231 @Override 232 public final Object getProperty(String propUri) { 233 return pl.fetchProperty(getId(), propUri); 234 } 235 236 @Override 237 public final boolean hasProperty(String propUri) { 238 return pl.hasProperty(getId(), propUri); 239 } 240 241 @Override 242 public final void setProperty(String propUri, Object propValue, boolean addToIndex) { 243 model.storeProperty(propUri, propValue, addToIndex); 244 } 245 246 @Override 247 public final void removeProperty(String propUri) { 248 model.removeProperty(propUri); 249 } 250 251 252 253 // === Misc === 254 255 @Override 256 public final Object getDatabaseVendorObject() { 257 return pl.getDatabaseVendorObject(getId()); 258 } 259 260 261 262 // ********************************** 263 // *** JSONEnabled Implementation *** 264 // ********************************** 265 266 267 268 @Override 269 public final JSONObject toJSON() { 270 return model.toJSON(); 271 } 272 273 274 275 // **************** 276 // *** Java API *** 277 // **************** 278 279 280 281 @Override 282 public final boolean equals(Object o) { 283 return ((DeepaMehtaObjectImpl) o).model.equals(model); 284 } 285 286 @Override 287 public final int hashCode() { 288 return model.hashCode(); 289 } 290 291 @Override 292 public final String toString() { 293 return model.toString(); 294 } 295 296 297 298 // ----------------------------------------------------------------------------------------- Package Private Methods 299 300 final String className() { 301 return model.className(); 302 } 303}