001 package de.deepamehta.core.impl; 002 003 import de.deepamehta.core.Association; 004 import de.deepamehta.core.RelatedAssociation; 005 import de.deepamehta.core.RelatedTopic; 006 import de.deepamehta.core.Topic; 007 import de.deepamehta.core.TopicType; 008 import de.deepamehta.core.model.AssociationModel; 009 import de.deepamehta.core.model.RelatedAssociationModel; 010 import de.deepamehta.core.model.RelatedTopicModel; 011 import de.deepamehta.core.model.SimpleValue; 012 import de.deepamehta.core.model.TopicModel; 013 import de.deepamehta.core.service.Directive; 014 import de.deepamehta.core.service.Directives; 015 import de.deepamehta.core.service.ResultList; 016 017 import java.util.List; 018 import java.util.logging.Logger; 019 020 021 022 /** 023 * A topic that is attached to the {@link DeepaMehtaService}. 024 */ 025 class AttachedTopic extends AttachedDeepaMehtaObject implements Topic { 026 027 // ---------------------------------------------------------------------------------------------- Instance Variables 028 029 private Logger logger = Logger.getLogger(getClass().getName()); 030 031 // ---------------------------------------------------------------------------------------------------- Constructors 032 033 AttachedTopic(TopicModel model, EmbeddedService dms) { 034 super(model, dms); 035 } 036 037 // -------------------------------------------------------------------------------------------------- Public Methods 038 039 040 041 // ****************************************** 042 // *** AttachedDeepaMehtaObject Overrides *** 043 // ****************************************** 044 045 046 047 // === Updating === 048 049 @Override 050 public void update(TopicModel model) { 051 _update(model); 052 // 053 dms.fireEvent(CoreEvent.POST_UPDATE_TOPIC_REQUEST, this); 054 } 055 056 057 058 // === Deletion === 059 060 @Override 061 public void delete() { 062 try { 063 dms.fireEvent(CoreEvent.PRE_DELETE_TOPIC, this); 064 // 065 // delete sub-topics and associations 066 super.delete(); 067 // delete topic itself 068 logger.info("Deleting " + this); 069 Directives.get().add(Directive.DELETE_TOPIC, this); 070 dms.storageDecorator.deleteTopic(getId()); 071 // 072 dms.fireEvent(CoreEvent.POST_DELETE_TOPIC, this); 073 } catch (Exception e) { 074 throw new RuntimeException("Deleting topic failed (" + this + ")", e); 075 } 076 } 077 078 079 080 // **************************** 081 // *** Topic Implementation *** 082 // **************************** 083 084 085 086 @Override 087 public Topic loadChildTopics() { 088 return (Topic) super.loadChildTopics(); 089 } 090 091 @Override 092 public Topic loadChildTopics(String childTypeUri) { 093 return (Topic) super.loadChildTopics(childTypeUri); 094 } 095 096 // --- 097 098 @Override 099 public TopicModel getModel() { 100 return (TopicModel) super.getModel(); 101 } 102 103 104 105 // *************************************** 106 // *** DeepaMehtaObject Implementation *** 107 // *************************************** 108 109 110 111 // === Traversal === 112 113 // --- Topic Retrieval --- 114 115 @Override 116 public ResultList<RelatedTopic> getRelatedTopics(List assocTypeUris, String myRoleTypeUri, String othersRoleTypeUri, 117 String othersTopicTypeUri, int maxResultSize) { 118 ResultList<RelatedTopicModel> topics = dms.storageDecorator.fetchTopicRelatedTopics(getId(), 119 assocTypeUris, myRoleTypeUri, othersRoleTypeUri, othersTopicTypeUri, maxResultSize); 120 return dms.instantiateRelatedTopics(topics); 121 } 122 123 // --- Association Retrieval --- 124 125 @Override 126 public RelatedAssociation getRelatedAssociation(String assocTypeUri, String myRoleTypeUri, 127 String othersRoleTypeUri, String othersAssocTypeUri) { 128 RelatedAssociationModel assoc = dms.storageDecorator.fetchTopicRelatedAssociation(getId(), 129 assocTypeUri, myRoleTypeUri, othersRoleTypeUri, othersAssocTypeUri); 130 return assoc != null ? dms.instantiateRelatedAssociation(assoc) : null; 131 } 132 133 @Override 134 public ResultList<RelatedAssociation> getRelatedAssociations(String assocTypeUri, String myRoleTypeUri, 135 String othersRoleTypeUri, String othersAssocTypeUri) { 136 ResultList<RelatedAssociationModel> assocs = dms.storageDecorator.fetchTopicRelatedAssociations(getId(), 137 assocTypeUri, myRoleTypeUri, othersRoleTypeUri, othersAssocTypeUri); 138 return dms.instantiateRelatedAssociations(assocs); 139 } 140 141 // --- 142 143 @Override 144 public Association getAssociation(String assocTypeUri, String myRoleTypeUri, String othersRoleTypeUri, 145 long othersTopicId) { 146 AssociationModel assoc = dms.storageDecorator.fetchAssociation(assocTypeUri, getId(), othersTopicId, 147 myRoleTypeUri, othersRoleTypeUri); 148 return assoc != null ? dms.instantiateAssociation(assoc) : null; 149 } 150 151 @Override 152 public List<Association> getAssociations() { 153 return dms.instantiateAssociations(dms.storageDecorator.fetchTopicAssociations(getId())); 154 } 155 156 157 158 // === Properties === 159 160 @Override 161 public Object getProperty(String propUri) { 162 return dms.storageDecorator.fetchTopicProperty(getId(), propUri); 163 } 164 165 @Override 166 public void setProperty(String propUri, Object propValue, boolean addToIndex) { 167 dms.storageDecorator.storeTopicProperty(getId(), propUri, propValue, addToIndex); 168 } 169 170 @Override 171 public boolean hasProperty(String propUri) { 172 return dms.storageDecorator.hasTopicProperty(getId(), propUri); 173 } 174 175 @Override 176 public void removeProperty(String propUri) { 177 dms.storageDecorator.removeTopicProperty(getId(), propUri); 178 } 179 180 181 182 // ----------------------------------------------------------------------------------------- Package Private Methods 183 184 /** 185 * Convenience method. 186 */ 187 TopicType getTopicType() { 188 return (TopicType) getType(); 189 } 190 191 /** 192 * Low-level update method which does not fire the POST_UPDATE_TOPIC_REQUEST event. 193 * <p> 194 * Called multiple times while updating the child topics (see AttachedChildTopics). 195 * POST_UPDATE_TOPIC_REQUEST on the other hand must be fired only once (per update request). 196 */ 197 void _update(TopicModel model) { 198 logger.info("Updating topic " + getId() + " (new " + model + ")"); 199 // 200 dms.fireEvent(CoreEvent.PRE_UPDATE_TOPIC, this, model); 201 // 202 TopicModel oldModel = getModel().clone(); 203 super.update(model); 204 // 205 addUpdateDirective(); 206 // 207 dms.fireEvent(CoreEvent.POST_UPDATE_TOPIC, this, model, oldModel); 208 } 209 210 211 212 // === Implementation of the abstract methods === 213 214 @Override 215 String className() { 216 return "topic"; 217 } 218 219 @Override 220 void addUpdateDirective() { 221 Directives.get().add(Directive.UPDATE_TOPIC, this); 222 } 223 224 @Override 225 final void storeUri() { 226 dms.storageDecorator.storeTopicUri(getId(), getUri()); 227 } 228 229 @Override 230 final void storeTypeUri() { 231 reassignInstantiation(); 232 dms.storageDecorator.storeTopicTypeUri(getId(), getTypeUri()); 233 } 234 235 // --- 236 237 @Override 238 final RelatedTopicModel fetchRelatedTopic(String assocTypeUri, String myRoleTypeUri, 239 String othersRoleTypeUri, String othersTopicTypeUri) { 240 return dms.storageDecorator.fetchTopicRelatedTopic(getId(), assocTypeUri, myRoleTypeUri, othersRoleTypeUri, 241 othersTopicTypeUri); 242 } 243 244 @Override 245 final ResultList<RelatedTopicModel> fetchRelatedTopics(String assocTypeUri, String myRoleTypeUri, 246 String othersRoleTypeUri, String othersTopicTypeUri, 247 int maxResultSize) { 248 return dms.storageDecorator.fetchTopicRelatedTopics(getId(), assocTypeUri, myRoleTypeUri, othersRoleTypeUri, 249 othersTopicTypeUri, maxResultSize); 250 } 251 252 253 254 // ------------------------------------------------------------------------------------------------- Private Methods 255 256 private void reassignInstantiation() { 257 // remove current assignment 258 fetchInstantiation().delete(); 259 // create new assignment 260 dms.createTopicInstantiation(getId(), getTypeUri()); 261 } 262 263 // Note: this method works only for instances, not for types. 264 // This is because a type is not of type "dm4.core.topic_type" but of type "dm4.core.meta_type". 265 private Association fetchInstantiation() { 266 RelatedTopic topicType = getRelatedTopic("dm4.core.instantiation", "dm4.core.instance", "dm4.core.type", 267 "dm4.core.topic_type"); 268 // 269 if (topicType == null) { 270 throw new RuntimeException("Topic " + getId() + " is not associated to a topic type"); 271 } 272 // 273 return topicType.getRelatingAssociation(); 274 } 275 }