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}