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