001package de.deepamehta.core.service; 002 003import de.deepamehta.core.Association; 004import de.deepamehta.core.AssociationType; 005import de.deepamehta.core.DeepaMehtaObject; 006import de.deepamehta.core.RelatedAssociation; 007import de.deepamehta.core.RelatedTopic; 008import de.deepamehta.core.Topic; 009import de.deepamehta.core.TopicType; 010import de.deepamehta.core.model.AssociationModel; 011import de.deepamehta.core.model.AssociationTypeModel; 012import de.deepamehta.core.model.SimpleValue; 013import de.deepamehta.core.model.TopicModel; 014import de.deepamehta.core.model.TopicTypeModel; 015import de.deepamehta.core.service.accesscontrol.AccessControl; 016import de.deepamehta.core.storage.spi.DeepaMehtaTransaction; 017 018import java.util.List; 019 020 021 022/** 023 * Specification of the DeepaMehta core service -- the heart of DeepaMehta. 024 * <p> 025 * The responsibility of the DeepaMehta core service is to orchestrate the control flow and allow plugins to hook in. 026 * The main duties of the DeepaMehta core service are to provide access to the storage layer and to dispatch events to 027 * the installed plugins. ### FIXDOC 028 * <p> 029 * The DeepaMehta core service is a realization of the <i>Inversion of Control</i> pattern. 030 * <p> 031 * The DeepaMehta core service provides methods to deal with topics, associations, types, and plugins. 032 * <p> 033 * Plugin developer notes: Inside the {@link PluginActivator} and {@link Migration} classes an instance of the 034 * DeepaMehta core service is available through the <code>dm4</code> object. 035 */ 036public interface CoreService { 037 038 039 040 // === Topics === 041 042 /** 043 * Accesses a topic by ID. 044 * 045 * @return the topic. 046 * 047 * @throws RuntimeException if no such topic exists. 048 */ 049 Topic getTopic(long topicId); 050 051 /** 052 * Accesses a topic by URI. 053 * 054 * @return the topic, or <code>null</code> if no such topic exists. 055 */ 056 Topic getTopicByUri(String uri); 057 058 /** 059 * Looks up a single topic by exact value. 060 * <p> 061 * Note: wildcards like "*" in String values are <i>not</i> interpreted. They are treated literally. 062 * Compare to {@link #getTopicsByValue(String,SimpleValue)} 063 * <p> 064 * IMPORTANT: Looking up a topic this way requires the corresponding type to be indexed with indexing mode 065 * <code>dm4.core.key</code>. 066 * 067 * @return the topic, or <code>null</code> if no such topic exists. 068 * 069 * @throws RuntimeException If more than one topic is found. 070 */ 071 Topic getTopicByValue(String key, SimpleValue value); 072 073 /** 074 * Looks up topics by key and value. 075 * <p> 076 * Wildcards like "*" in String values are interpreted. 077 * <p> 078 * IMPORTANT: Looking up topics this way requires the corresponding type to be indexed with indexing mode 079 * <code>dm4.core.key</code>. 080 */ 081 List<Topic> getTopicsByValue(String key, SimpleValue value); 082 083 List<Topic> getTopicsByType(String topicTypeUri); 084 085 /** 086 * Performs a fulltext search. 087 * <p> 088 * IMPORTANT: Searching topics this way requires the corresponding type to be indexed with indexing mode 089 * <code>dm4.core.fulltext</code> or <code>dm4.core.fulltext_key</code>. ### FIXDOC 090 * 091 * @param fieldUri The URI of the data field to search. If null is provided all fields are searched. ### FIXDOC 092 * ### TODO: rename parameter to "key"? 093 */ 094 List<Topic> searchTopics(String searchTerm, String fieldUri); 095 096 Iterable<Topic> getAllTopics(); 097 098 // --- 099 100 Topic createTopic(TopicModel model); 101 102 void updateTopic(TopicModel newModel); 103 104 void deleteTopic(long topicId); 105 106 107 108 // === Associations === 109 110 Association getAssociation(long assocId); 111 112 /** 113 * Looks up a single association by exact value. 114 * <p> 115 * Note: wildcards like "*" in String values are <i>not</i> interpreted. They are treated literally. 116 * Compare to {@link #getAssociationsByValue(String,SimpleValue)} 117 * <p> 118 * IMPORTANT: Looking up an association this way requires the corresponding type to be indexed with indexing mode 119 * <code>dm4.core.key</code>. 120 * 121 * @return the association, or <code>null</code> if no such association exists. 122 * 123 * @throws RuntimeException If more than one association is found. 124 */ 125 Association getAssociationByValue(String key, SimpleValue value); 126 127 /** 128 * Looks up associations by key and value. 129 * <p> 130 * Wildcards like "*" in String values <i>are</i> interpreted. 131 * <p> 132 * IMPORTANT: Looking up associations this way requires the corresponding type to be indexed with indexing mode 133 * <code>dm4.core.key</code>. 134 */ 135 List<Association> getAssociationsByValue(String key, SimpleValue value); 136 137 /** 138 * Returns the association between two topics, qualified by association type and both role types. 139 * If no such association exists <code>null</code> is returned. 140 * If more than one association exist, a runtime exception is thrown. 141 * 142 * @param assocTypeUri Association type filter. Pass <code>null</code> to switch filter off. 143 */ 144 Association getAssociation(String assocTypeUri, long topic1Id, long topic2Id, 145 String roleTypeUri1, String roleTypeUri2); 146 147 Association getAssociationBetweenTopicAndAssociation(String assocTypeUri, long topicId, long assocId, 148 String topicRoleTypeUri, String assocRoleTypeUri); 149 150 // --- 151 152 List<Association> getAssociationsByType(String assocTypeUri); 153 154 /** 155 * Returns all associations between two topics. If no such association exists an empty set is returned. 156 */ 157 List<Association> getAssociations(long topic1Id, long topic2Id); 158 159 /** 160 * Returns the associations between two topics. If no such association exists an empty set is returned. 161 * 162 * @param assocTypeUri Association type filter. Pass <code>null</code> to switch filter off. 163 */ 164 List<Association> getAssociations(long topic1Id, long topic2Id, String assocTypeUri); 165 166 // --- 167 168 Iterable<Association> getAllAssociations(); 169 170 long[] getPlayerIds(long assocId); 171 172 // --- 173 174 Association createAssociation(AssociationModel model); 175 176 void updateAssociation(AssociationModel newModel); 177 178 void deleteAssociation(long assocId); 179 180 181 182 // === Topic Types === 183 184 List<String> getTopicTypeUris(); 185 186 TopicType getTopicType(String topicTypeUri); 187 188 List<TopicType> getAllTopicTypes(); 189 190 // --- 191 192 TopicType createTopicType(TopicTypeModel model); 193 194 void updateTopicType(TopicTypeModel newModel); 195 196 void deleteTopicType(String topicTypeUri); 197 198 199 200 // === Association Types === 201 202 List<String> getAssociationTypeUris(); 203 204 AssociationType getAssociationType(String assocTypeUri); 205 206 List<AssociationType> getAllAssociationTypes(); 207 208 // --- 209 210 AssociationType createAssociationType(AssociationTypeModel model); 211 212 void updateAssociationType(AssociationTypeModel newModel); 213 214 void deleteAssociationType(String assocTypeUri); 215 216 217 218 // === Role Types === 219 220 Topic createRoleType(TopicModel model); 221 222 223 224 // === Generic Object === 225 226 DeepaMehtaObject getObject(long id); 227 228 229 230 // === Plugins === 231 232 Plugin getPlugin(String pluginUri); 233 234 List<PluginInfo> getPluginInfo(); 235 236 237 238 // === Events === 239 240 void fireEvent(DeepaMehtaEvent event, Object... params); 241 242 void dispatchEvent(String pluginUri, DeepaMehtaEvent event, Object... params); 243 244 245 246 // === Properties === 247 248 /** 249 * Returns a topic's or association's property value associated with the given property URI. 250 * If there's no property value associated with the property URI an exception is thrown. 251 * 252 * @param id a topic ID, or an association ID 253 */ 254 Object getProperty(long id, String propUri); 255 256 /** 257 * Checks whether for a given topic or association a property value is associated with a given property URI. 258 * 259 * @param id a topic ID, or an association ID 260 */ 261 boolean hasProperty(long id, String propUri); 262 263 // Note: there is no setter here. If we want one we actually need 2 setters: one for topics, one for assocs. 264 // This is because the storage layer maintains separate indexes for topics and assocs. 265 266 // --- 267 268 List<Topic> getTopicsByProperty(String propUri, Object propValue); 269 270 List<Topic> getTopicsByPropertyRange(String propUri, Number from, Number to); 271 272 List<Association> getAssociationsByProperty(String propUri, Object propValue); 273 274 List<Association> getAssociationsByPropertyRange(String propUri, Number from, Number to); 275 276 // --- 277 278 void addTopicPropertyIndex(String propUri); 279 280 void addAssociationPropertyIndex(String propUri); 281 282 283 284 // === Misc === 285 286 DeepaMehtaTransaction beginTx(); 287 288 // --- 289 290 ModelFactory getModelFactory(); 291 292 AccessControl getAccessControl(); // ### TODO: drop this 293 294 Object getDatabaseVendorObject(); 295}