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