001 package de.deepamehta.plugins.facets; 002 003 import de.deepamehta.plugins.facets.service.FacetsService; 004 005 import de.deepamehta.core.Association; 006 import de.deepamehta.core.AssociationDefinition; 007 import de.deepamehta.core.DeepaMehtaObject; 008 import de.deepamehta.core.RelatedTopic; 009 import de.deepamehta.core.Topic; 010 import de.deepamehta.core.model.AssociationModel; 011 import de.deepamehta.core.model.TopicModel; 012 import de.deepamehta.core.model.TopicRoleModel; 013 import de.deepamehta.core.osgi.PluginActivator; 014 import de.deepamehta.core.service.ClientState; 015 import de.deepamehta.core.service.Directives; 016 017 import java.util.List; 018 import java.util.logging.Logger; 019 020 021 022 public class FacetsPlugin extends PluginActivator implements FacetsService { 023 024 // ---------------------------------------------------------------------------------------------- Instance Variables 025 026 private Logger logger = Logger.getLogger(getClass().getName()); 027 028 // -------------------------------------------------------------------------------------------------- Public Methods 029 030 031 032 // ************************************ 033 // *** FacetsService Implementation *** 034 // ************************************ 035 036 037 038 @Override 039 public Topic getFacet(long topicId, String facetTypeUri) { 040 Topic topic = dms.getTopic(topicId, false); // fetchComposite=false 041 return getFacet(topic, facetTypeUri); 042 } 043 044 @Override 045 public Topic getFacet(DeepaMehtaObject object, String facetTypeUri) { 046 // ### TODO: integrity check: is the object an instance of that facet type? 047 return fetchChildTopic(object, getAssocDef(facetTypeUri), true); // fetchComposite=true 048 } 049 050 // --- 051 052 @Override 053 public List<RelatedTopic> getFacets(DeepaMehtaObject object, String facetTypeUri) { 054 // ### TODO: integrity check: is the object an instance of that facet type? 055 return fetchChildTopics(object, getAssocDef(facetTypeUri), true); // fetchComposite=true 056 } 057 058 // --- 059 060 @Override 061 public void addFacetTypeToTopic(long topicId, String facetTypeUri) { 062 dms.createAssociation(new AssociationModel("dm4.core.instantiation", 063 new TopicRoleModel(topicId, "dm4.core.instance"), 064 new TopicRoleModel(facetTypeUri, "dm4.facets.facet")), null); // clientState=null 065 } 066 067 // --- 068 069 @Override 070 public void updateFacet(DeepaMehtaObject object, String facetTypeUri, TopicModel facetValue, 071 ClientState clientState, Directives directives) { 072 // ### TODO: incorporate the Facets module into the DeepaMehta core? 073 object.updateChildTopic(facetValue, getAssocDef(facetTypeUri), clientState, directives); 074 } 075 076 @Override 077 public void updateFacets(DeepaMehtaObject object, String facetTypeUri, List<? extends TopicModel> facetValues, 078 ClientState clientState, Directives directives) { 079 // ### TODO: incorporate the Facets module into the DeepaMehta core? 080 object.updateChildTopics(facetValues, getAssocDef(facetTypeUri), clientState, directives); 081 } 082 083 // --- 084 085 // Note: there is a similar private method in AttachedDeepaMehtaObject: 086 // fetchChildTopic(AssociationDefinition assocDef, long childTopicId, boolean fetchComposite) 087 // ### TODO: Extend DeepaMehtaObject interface by hasChildTopic()? 088 @Override 089 public boolean hasFacet(long topicId, String facetTypeUri, long facetTopicId) { 090 String assocTypeUri = getAssocDef(facetTypeUri).getInstanceLevelAssocTypeUri(); 091 Association assoc = dms.getAssociation(assocTypeUri, topicId, facetTopicId, "dm4.core.parent", "dm4.core.child", 092 false); // fetchComposite=false 093 return assoc != null; 094 } 095 096 097 098 // ------------------------------------------------------------------------------------------------- Private Methods 099 100 /** 101 * Fetches and returns a child topic or <code>null</code> if no such topic extists. 102 * <p> 103 * Note: There is a principal copy in AttachedDeepaMehtaObject but here the precondition is different: 104 * The given association definition must not necessarily originate from the given object's type definition. 105 * ### TODO: meanwhile we have the ValueStorage. Can we use its method instead? 106 */ 107 private RelatedTopic fetchChildTopic(DeepaMehtaObject object, AssociationDefinition assocDef, 108 boolean fetchComposite) { 109 String assocTypeUri = assocDef.getInstanceLevelAssocTypeUri(); 110 String othersTypeUri = assocDef.getChildTypeUri(); 111 return object.getRelatedTopic(assocTypeUri, "dm4.core.parent", "dm4.core.child", othersTypeUri, fetchComposite, 112 false); 113 } 114 115 /** 116 * Fetches and returns child topics. 117 * <p> 118 * Note: There is a principal copy in AttachedDeepaMehtaObject but here the precondition is different: 119 * The given association definition must not necessarily originate from the given object's type definition. 120 * ### TODO: meanwhile we have the ValueStorage. Can we use its method instead? 121 */ 122 private List<RelatedTopic> fetchChildTopics(DeepaMehtaObject object, AssociationDefinition assocDef, 123 boolean fetchComposite) { 124 String assocTypeUri = assocDef.getInstanceLevelAssocTypeUri(); 125 String othersTypeUri = assocDef.getChildTypeUri(); 126 return object.getRelatedTopics(assocTypeUri, "dm4.core.parent", "dm4.core.child", othersTypeUri, fetchComposite, 127 false, 0).getItems(); 128 } 129 130 // --- 131 132 private AssociationDefinition getAssocDef(String facetTypeUri) { 133 // Note: a facet type has exactly *one* association definition 134 return dms.getTopicType(facetTypeUri).getAssocDefs().iterator().next(); 135 } 136 }