001package systems.dmx.core.service; 002 003import systems.dmx.core.Association; 004import systems.dmx.core.AssociationType; 005import systems.dmx.core.DMXObject; 006import systems.dmx.core.RelatedAssociation; 007import systems.dmx.core.RelatedTopic; 008import systems.dmx.core.Topic; 009import systems.dmx.core.TopicType; 010import systems.dmx.core.model.AssociationModel; 011import systems.dmx.core.model.AssociationTypeModel; 012import systems.dmx.core.model.SimpleValue; 013import systems.dmx.core.model.TopicModel; 014import systems.dmx.core.model.TopicTypeModel; 015import systems.dmx.core.service.accesscontrol.AccessControl; 016import systems.dmx.core.storage.spi.DMXTransaction; 017 018import java.util.List; 019 020 021 022/** 023 * Specification of the DMX core service -- the heart of DMX. 024 * <p> 025 * The responsibility of the DMX core service is to orchestrate the control flow and allow plugins to hook in. 026 * The main duties of the DMX core service are to provide access to the storage layer and to dispatch events to 027 * the installed plugins. ### FIXDOC 028 * <p> 029 * The DMX core service is a realization of the <i>Inversion of Control</i> pattern. 030 * <p> 031 * The DMX 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 * DMX core service is available through the <code>dmx</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>dmx.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>dmx.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>dmx.core.fulltext</code> or <code>dmx.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"/"typeUri"? 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 updateModel); 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>dmx.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>dmx.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 list 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 list 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 updateModel); 177 178 void deleteAssociation(long assocId); 179 180 181 182 // === Topic Types === 183 184 TopicType getTopicType(String topicTypeUri); 185 186 /** 187 * Acccesses a topic type while enforcing the <i>implicit READ permission</i>. 188 * A user has implicit READ permission for the topic type if she has READ permission for the given topic. 189 */ 190 TopicType getTopicTypeImplicitly(long topicId); 191 192 // --- 193 194 List<TopicType> getAllTopicTypes(); 195 196 // --- 197 198 TopicType createTopicType(TopicTypeModel model); 199 200 void updateTopicType(TopicTypeModel updateModel); 201 202 void deleteTopicType(String topicTypeUri); 203 204 205 206 // === Association Types === 207 208 AssociationType getAssociationType(String assocTypeUri); 209 210 /** 211 * Acccesses an association type while enforcing the <i>implicit READ permission</i>. 212 * A user has implicit READ permission for the association type if she has READ permission for the given 213 * association. 214 */ 215 AssociationType getAssociationTypeImplicitly(long assocId); 216 217 // --- 218 219 List<AssociationType> getAllAssociationTypes(); 220 221 // --- 222 223 AssociationType createAssociationType(AssociationTypeModel model); 224 225 void updateAssociationType(AssociationTypeModel updateModel); 226 227 void deleteAssociationType(String assocTypeUri); 228 229 230 231 // === Role Types === 232 233 Topic createRoleType(TopicModel model); 234 235 236 237 // === Generic Object === 238 239 DMXObject getObject(long id); 240 241 242 243 // === Plugins === 244 245 Plugin getPlugin(String pluginUri); 246 247 List<PluginInfo> getPluginInfo(); 248 249 250 251 // === Events === 252 253 void fireEvent(DMXEvent event, Object... params); 254 255 void dispatchEvent(String pluginUri, DMXEvent event, Object... params); 256 257 258 259 // === Properties === 260 261 /** 262 * Returns a topic's or association's property value associated with the given property URI. 263 * If there's no property value associated with the property URI an exception is thrown. 264 * 265 * @param id a topic ID, or an association ID 266 */ 267 Object getProperty(long id, String propUri); 268 269 /** 270 * Checks whether for a given topic or association a property value is associated with a given property URI. 271 * 272 * @param id a topic ID, or an association ID 273 */ 274 boolean hasProperty(long id, String propUri); 275 276 // Note: there is no setter here. If we want one we actually need 2 setters: one for topics, one for assocs. 277 // This is because the storage layer maintains separate indexes for topics and assocs. 278 279 // --- 280 281 List<Topic> getTopicsByProperty(String propUri, Object propValue); 282 283 List<Topic> getTopicsByPropertyRange(String propUri, Number from, Number to); 284 285 List<Association> getAssociationsByProperty(String propUri, Object propValue); 286 287 List<Association> getAssociationsByPropertyRange(String propUri, Number from, Number to); 288 289 // --- 290 291 void addTopicPropertyIndex(String propUri); 292 293 void addAssociationPropertyIndex(String propUri); 294 295 296 297 // === Misc === 298 299 DMXTransaction beginTx(); 300 301 // --- 302 303 ModelFactory getModelFactory(); 304 305 AccessControl getAccessControl(); // ### TODO: drop this 306 307 WebSocketsService getWebSocketsService(); 308 309 Object getDatabaseVendorObject(); 310}