001package de.deepamehta.core.impl; 002 003import de.deepamehta.core.Topic; 004import de.deepamehta.core.model.AssociationDefinitionModel; 005import de.deepamehta.core.model.ChildTopicsModel; 006import de.deepamehta.core.model.IndexMode; 007import de.deepamehta.core.model.RoleModel; 008import de.deepamehta.core.model.TopicModel; 009import de.deepamehta.core.model.TopicTypeModel; 010import de.deepamehta.core.model.TypeModel; 011import de.deepamehta.core.service.DeepaMehtaEvent; 012import de.deepamehta.core.service.Directive; 013 014import java.util.List; 015 016 017 018class TopicModelImpl extends DeepaMehtaObjectModelImpl implements TopicModel { 019 020 // ---------------------------------------------------------------------------------------------------- Constructors 021 022 TopicModelImpl(DeepaMehtaObjectModelImpl object) { 023 super(object); 024 } 025 026 // -------------------------------------------------------------------------------------------------- Public Methods 027 028 029 030 // === Implementation of the abstract methods === 031 032 @Override 033 public RoleModel createRoleModel(String roleTypeUri) { 034 return mf.newTopicRoleModel(id, roleTypeUri); 035 } 036 037 038 039 // === Java API === 040 041 @Override 042 public TopicModel clone() { 043 try { 044 return (TopicModel) super.clone(); 045 } catch (Exception e) { 046 throw new RuntimeException("Cloning a TopicModel failed", e); 047 } 048 } 049 050 @Override 051 public String toString() { 052 return "topic (" + super.toString() + ")"; 053 } 054 055 056 057 // ----------------------------------------------------------------------------------------- Package Private Methods 058 059 @Override 060 String className() { 061 return "topic"; 062 } 063 064 @Override 065 TopicImpl instantiate() { 066 return new TopicImpl(this, pl); 067 } 068 069 // --- 070 071 @Override 072 TopicTypeModel getType() { 073 return pl.typeStorage.getTopicType(typeUri); 074 } 075 076 @Override 077 List<AssociationModelImpl> getAssociations() { 078 return pl.fetchTopicAssociations(id); 079 } 080 081 // --- 082 083 @Override 084 RelatedTopicModelImpl getRelatedTopic(String assocTypeUri, String myRoleTypeUri, String othersRoleTypeUri, 085 String othersTopicTypeUri) { 086 return pl.fetchTopicRelatedTopic(id, assocTypeUri, myRoleTypeUri, othersRoleTypeUri, othersTopicTypeUri); 087 } 088 089 @Override 090 List<RelatedTopicModelImpl> getRelatedTopics(String assocTypeUri, String myRoleTypeUri, String othersRoleTypeUri, 091 String othersTopicTypeUri) { 092 return pl.fetchTopicRelatedTopics(id, assocTypeUri, myRoleTypeUri, othersRoleTypeUri, othersTopicTypeUri); 093 } 094 095 @Override 096 List<RelatedTopicModelImpl> getRelatedTopics(List assocTypeUris, String myRoleTypeUri, String othersRoleTypeUri, 097 String othersTopicTypeUri) { 098 return pl.fetchTopicRelatedTopics(id, assocTypeUris, myRoleTypeUri, othersRoleTypeUri, othersTopicTypeUri); 099 } 100 101 // --- 102 103 @Override 104 void storeUri() { 105 pl.storeTopicUri(id, uri); 106 } 107 108 @Override 109 void storeTypeUri() { 110 reassignInstantiation(); 111 pl.storeTopicTypeUri(id, typeUri); 112 } 113 114 @Override 115 void storeSimpleValue() { 116 TypeModel type = getType(); 117 pl.storeTopicValue(id, value, type.getIndexModes(), type.getUri(), getIndexValue()); 118 } 119 120 @Override 121 void indexSimpleValue(IndexMode indexMode) { 122 pl.indexTopicValue(id, indexMode, typeUri, getIndexValue()); 123 } 124 125 // --- 126 127 @Override 128 void updateChildTopics(ChildTopicsModel childTopics) { 129 update(mf.newTopicModel(childTopics)); 130 } 131 132 @Override 133 void _delete() { 134 pl._deleteTopic(id); 135 } 136 137 // --- 138 139 @Override 140 DeepaMehtaEvent getReadAccessEvent() { 141 return CoreEvent.CHECK_TOPIC_READ_ACCESS; 142 } 143 144 @Override 145 DeepaMehtaEvent getPreUpdateEvent() { 146 return CoreEvent.PRE_UPDATE_TOPIC; 147 } 148 149 @Override 150 DeepaMehtaEvent getPostUpdateEvent() { 151 return CoreEvent.POST_UPDATE_TOPIC; 152 } 153 154 @Override 155 DeepaMehtaEvent getPreDeleteEvent() { 156 return CoreEvent.PRE_DELETE_TOPIC; 157 } 158 159 @Override 160 DeepaMehtaEvent getPostDeleteEvent() { 161 return CoreEvent.POST_DELETE_TOPIC; 162 } 163 164 // --- 165 166 @Override 167 Directive getUpdateDirective() { 168 return Directive.UPDATE_TOPIC; 169 } 170 171 @Override 172 Directive getDeleteDirective() { 173 return Directive.DELETE_TOPIC; 174 } 175 176 177 178 // === Core Internal Hooks === 179 180 @Override 181 void preDelete() { 182 if (typeUri.equals("dm4.core.topic_type") || typeUri.equals("dm4.core.assoc_type")) { 183 throw new RuntimeException("Tried to delete a type with a generic delete-topic call. " + 184 "Use a delete-type call instead."); 185 } 186 } 187 188 189 190 // === 191 192 TopicModelImpl findChildTopic(String topicTypeUri) { 193 if (typeUri.equals(topicTypeUri)) { 194 return this; 195 } 196 // 197 for (AssociationDefinitionModel assocDef : getType().getAssocDefs()) { 198 String assocDefUri = assocDef.getAssocDefUri(); 199 String cardinalityUri = assocDef.getChildCardinalityUri(); 200 TopicModelImpl childTopic = null; 201 if (cardinalityUri.equals("dm4.core.one")) { 202 childTopic = childTopics.getTopicOrNull(assocDefUri); // no load from DB 203 } else if (cardinalityUri.equals("dm4.core.many")) { 204 List<RelatedTopicModelImpl> _childTopics = childTopics.getTopicsOrNull(assocDefUri); // no load from DB 205 if (_childTopics != null && !_childTopics.isEmpty()) { 206 childTopic = _childTopics.get(0); 207 } 208 } else { 209 throw new RuntimeException("\"" + cardinalityUri + "\" is an unexpected cardinality URI"); 210 } 211 // Note: topics just created have no child topics yet 212 if (childTopic == null) { 213 continue; 214 } 215 // recursion 216 childTopic = childTopic.findChildTopic(topicTypeUri); 217 if (childTopic != null) { 218 return childTopic; 219 } 220 } 221 return null; 222 } 223 224 225 226 // ------------------------------------------------------------------------------------------------- Private Methods 227 228 private void reassignInstantiation() { 229 // remove current assignment 230 fetchInstantiation().delete(); 231 // create new assignment 232 pl.createTopicInstantiation(id, typeUri); 233 } 234 235 // Note: this method works only for instances, not for types. 236 // This is because a type is not of type "dm4.core.topic_type" but of type "dm4.core.meta_type". 237 private AssociationModelImpl fetchInstantiation() { 238 RelatedTopicModelImpl topicType = getRelatedTopic("dm4.core.instantiation", "dm4.core.instance", 239 "dm4.core.type", "dm4.core.topic_type"); 240 // 241 if (topicType == null) { 242 throw new RuntimeException("Topic " + id + " is not associated to a topic type"); 243 } 244 // 245 return topicType.getRelatingAssociation(); 246 } 247}