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.ChildTopicsModel; 010 import de.deepamehta.core.model.RelatedAssociationModel; 011 import de.deepamehta.core.model.RelatedTopicModel; 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 void setProperty(String propUri, Object propValue, boolean addToIndex) { 162 dms.storageDecorator.storeTopicProperty(getId(), propUri, propValue, addToIndex); 163 } 164 165 @Override 166 public void removeProperty(String propUri) { 167 dms.storageDecorator.removeTopicProperty(getId(), propUri); 168 } 169 170 171 172 // ----------------------------------------------------------------------------------------- Package Private Methods 173 174 /** 175 * Low-level update method which does not fire the POST_UPDATE_TOPIC_REQUEST event. 176 * <p> 177 * Called multiple times while updating the child topics (see AttachedChildTopics). 178 * POST_UPDATE_TOPIC_REQUEST on the other hand must be fired only once (per update request). 179 */ 180 void _update(TopicModel model) { 181 logger.info("Updating topic " + getId() + " (new " + model + ")"); 182 // 183 dms.fireEvent(CoreEvent.PRE_UPDATE_TOPIC, this, model); 184 // 185 TopicModel oldModel = getModel().clone(); 186 super.update(model); 187 // 188 dms.fireEvent(CoreEvent.POST_UPDATE_TOPIC, this, model, oldModel); 189 } 190 191 192 193 // === Implementation of the abstract methods === 194 195 @Override 196 String className() { 197 return "topic"; 198 } 199 200 @Override 201 void updateChildTopics(ChildTopicsModel childTopics) { 202 update(new TopicModel(childTopics)); 203 } 204 205 @Override 206 Directive getUpdateDirective() { 207 return Directive.UPDATE_TOPIC; 208 } 209 210 @Override 211 final void storeUri() { 212 dms.storageDecorator.storeTopicUri(getId(), getUri()); 213 } 214 215 @Override 216 final void storeTypeUri() { 217 reassignInstantiation(); 218 dms.storageDecorator.storeTopicTypeUri(getId(), getTypeUri()); 219 } 220 221 // --- 222 223 @Override 224 final RelatedTopicModel fetchRelatedTopic(String assocTypeUri, String myRoleTypeUri, 225 String othersRoleTypeUri, String othersTopicTypeUri) { 226 return dms.storageDecorator.fetchTopicRelatedTopic(getId(), assocTypeUri, myRoleTypeUri, othersRoleTypeUri, 227 othersTopicTypeUri); 228 } 229 230 @Override 231 final ResultList<RelatedTopicModel> fetchRelatedTopics(String assocTypeUri, String myRoleTypeUri, 232 String othersRoleTypeUri, String othersTopicTypeUri, 233 int maxResultSize) { 234 return dms.storageDecorator.fetchTopicRelatedTopics(getId(), assocTypeUri, myRoleTypeUri, othersRoleTypeUri, 235 othersTopicTypeUri, maxResultSize); 236 } 237 238 // --- 239 240 @Override 241 TopicType getType() { 242 return dms.getTopicType(getTypeUri()); 243 } 244 245 246 247 // ------------------------------------------------------------------------------------------------- Private Methods 248 249 private void reassignInstantiation() { 250 // remove current assignment 251 fetchInstantiation().delete(); 252 // create new assignment 253 dms.createTopicInstantiation(getId(), getTypeUri()); 254 } 255 256 // Note: this method works only for instances, not for types. 257 // This is because a type is not of type "dm4.core.topic_type" but of type "dm4.core.meta_type". 258 private Association fetchInstantiation() { 259 RelatedTopic topicType = getRelatedTopic("dm4.core.instantiation", "dm4.core.instance", "dm4.core.type", 260 "dm4.core.topic_type"); 261 // 262 if (topicType == null) { 263 throw new RuntimeException("Topic " + getId() + " is not associated to a topic type"); 264 } 265 // 266 return topicType.getRelatingAssociation(); 267 } 268 }