001package systems.dmx.core.impl; 002 003import systems.dmx.core.model.AssociationDefinitionModel; 004import systems.dmx.core.model.ChildTopicsModel; 005import systems.dmx.core.model.DMXObjectModel; 006 007import java.util.List; 008import java.util.logging.Logger; 009 010 011 012class ChildTopicsFetcher { 013 014 // ---------------------------------------------------------------------------------------------- Instance Variables 015 016 private PersistenceLayer pl; 017 018 private Logger logger = Logger.getLogger(getClass().getName()); 019 020 // ---------------------------------------------------------------------------------------------------- Constructors 021 022 ChildTopicsFetcher(PersistenceLayer pl) { 023 this.pl = pl; 024 } 025 026 // ----------------------------------------------------------------------------------------- Package Private Methods 027 028 /** 029 * Fetches the child topic models (recursively) of the given object model and updates it in-place. 030 * ### TODO: recursion is required in some cases (e.g. when fetching a topic through REST API) but is possibly 031 * overhead in others (e.g. when updating composite structures). 032 * <p> 033 * Works for both, "one" and "many" association definitions. 034 * 035 * @param assocDef The child topic models according to this association definition are fetched. 036 */ 037 void fetch(DMXObjectModel object, AssociationDefinitionModel assocDef, boolean deep) { 038 try { 039 ChildTopicsModel childTopics = object.getChildTopicsModel(); 040 String cardinalityUri = assocDef.getChildCardinalityUri(); 041 String assocDefUri = assocDef.getAssocDefUri(); 042 if (cardinalityUri.equals("dmx.core.one")) { 043 RelatedTopicModelImpl childTopic = fetchChildTopic(object.getId(), assocDef); 044 // Note: topics just created have no child topics yet 045 if (childTopic != null) { 046 childTopics.put(assocDefUri, childTopic); 047 if (deep) { 048 fetchChildTopics(childTopic, deep); // recursion 049 } 050 } 051 } else if (cardinalityUri.equals("dmx.core.many")) { 052 for (RelatedTopicModelImpl childTopic : fetchChildTopics(object.getId(), assocDef)) { 053 childTopics.add(assocDefUri, childTopic); 054 if (deep) { 055 fetchChildTopics(childTopic, deep); // recursion 056 } 057 } 058 } else { 059 throw new RuntimeException("\"" + cardinalityUri + "\" is an unexpected cardinality URI"); 060 } 061 } catch (Exception e) { 062 throw new RuntimeException("Fetching the \"" + assocDef.getAssocDefUri() + "\" child topics of object " + 063 object.getId() + " failed", e); 064 } 065 } 066 067 // ------------------------------------------------------------------------------------------------- Private Methods 068 069 /** 070 * Fetches the child topic models (recursively) of the given object model and updates it in-place. 071 * ### TODO: recursion is required in some cases (e.g. when fetching a topic through REST API) but is possibly 072 * overhead in others (e.g. when updating composite structures). 073 */ 074 private void fetchChildTopics(DMXObjectModelImpl object, boolean deep) { 075 for (AssociationDefinitionModel assocDef : object.getType().getAssocDefs()) { 076 fetch(object, assocDef, deep); 077 } 078 } 079 080 // --- 081 082 /** 083 * Fetches and returns a child topic or <code>null</code> if no such topic extists. 084 */ 085 private RelatedTopicModelImpl fetchChildTopic(long objectId, AssociationDefinitionModel assocDef) { 086 return pl.fetchRelatedTopic( 087 objectId, 088 assocDef.getInstanceLevelAssocTypeUri(), 089 "dmx.core.parent", "dmx.core.child", 090 assocDef.getChildTypeUri() 091 ); 092 } 093 094 private List<RelatedTopicModelImpl> fetchChildTopics(long objectId, AssociationDefinitionModel assocDef) { 095 return pl.fetchRelatedTopics( 096 objectId, 097 assocDef.getInstanceLevelAssocTypeUri(), 098 "dmx.core.parent", "dmx.core.child", 099 assocDef.getChildTypeUri() 100 ); 101 } 102}