001package systems.dmx.core.impl; 002 003import systems.dmx.core.model.RelatedTopicModel; 004import systems.dmx.core.model.SimpleValue; 005import systems.dmx.core.model.TopicModel; 006import systems.dmx.core.model.TopicReferenceModel; 007 008import java.util.List; 009 010 011 012class TopicReferenceModelImpl extends RelatedTopicModelImpl implements TopicReferenceModel { 013 014 // ---------------------------------------------------------------------------------------------------- Constructors 015 016 TopicReferenceModelImpl(RelatedTopicModelImpl relatedTopic) { 017 super(relatedTopic); 018 } 019 020 // -------------------------------------------------------------------------------------------------- Public Methods 021 022 @Override 023 public boolean isReferenceById() { 024 return getId() != -1; 025 } 026 027 @Override 028 public boolean isReferenceByUri() { 029 return getUri() != null && !getUri().equals(""); 030 } 031 032 @Override 033 public boolean isEmptyRef() { 034 return !isReferenceById() && !isReferenceByUri(); 035 } 036 037 // --- 038 039 @Override 040 public boolean isReferingTo(TopicModel topic) { 041 if (isReferenceById()) { 042 return getId() == topic.getId(); 043 } else if (isReferenceByUri()) { 044 return getUri().equals(topic.getUri()); 045 } else { 046 throw new RuntimeException("Invalid " + this); 047 } 048 } 049 050 @Override 051 public RelatedTopicModelImpl findReferencedTopic(List<? extends RelatedTopicModel> topics) { 052 for (RelatedTopicModel topic : topics) { 053 if (isReferingTo(topic)) { 054 return (RelatedTopicModelImpl) topic; 055 } 056 } 057 return null; 058 } 059 060 // ----------------------------------------------------------------------------------------- Package Private Methods 061 062 @Override 063 String className() { 064 return "topic reference"; 065 } 066 067 // --- 068 069 /** 070 * Resolves this reference and replaces it by the resolved topic. 071 * 072 * TODO: don't manipulate in-place? 073 * 074 * @throws RuntimeException if retrieval of the refered topic fails 075 * @throws RuntimeException if this reference refers to nothing 076 */ 077 TopicModelImpl resolve() { 078 try { 079 TopicModelImpl topic; 080 // Note: the resolved topic must be fetched including its child topics. 081 // They might be required for label calculation and/or at client-side. ### TODO? 082 if (isReferenceById()) { 083 topic = pl.fetchTopic(id); // .loadChildTopics(); // TODO? 084 } else if (isReferenceByUri()) { 085 topic = pl.fetchTopic("uri", new SimpleValue(uri)); 086 if (topic == null) { 087 throw new RuntimeException("Topic with URI \"" + uri + "\" not found"); 088 } 089 // .loadChildTopics(); // TODO? 090 } else { 091 throw new RuntimeException("Invalid " + this); 092 } 093 // TODO: why is set() required? 094 // Without it the custom assoc type refs in the type cache are unresolved (ID=-1) after bootstrap 095 this.set(topic); 096 return topic; 097 } catch (Exception e) { 098 throw new RuntimeException("Resolving a topic reference failed (" + this + ")", e); 099 } 100 } 101}