From 3bbd5d6315039a6463042fe81a0da395b1ab871a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Richter?= Date: Sat, 20 Oct 2012 04:20:42 +0200 Subject: [PATCH] Core: refactor type construction pt.1 (#340). Former approach: Types are constructed with a model that is initialized only partial and then load and init the remaining parts themselfs. New concept: Construction of types is the responsibility of the object factory. Loading the model and constructing the actual type object from it are strictly separated. Never construct a type with a partly initialized model. Does not yet work. Do not install the "child-order" branch. Done - data type - index modes Pending - association definitions - label configuration - view configuration In preparation of "Child Topic Order". See ticket 340. --- .../de/deepamehta/core/DeepaMehtaObject.java | 12 +-- .../main/java/de/deepamehta/core/Topic.java | 2 + .../core/impl/service/AttachedType.java | 38 ++------- .../core/impl/service/EmbeddedService.java | 10 +-- .../core/impl/service/ObjectFactoryImpl.java | 82 +++++++++++++++++++ .../core/impl/service/TypeCache.java | 56 ++++--------- .../core/model/AssociationTypeModel.java | 5 +- .../de/deepamehta/core/model/IndexMode.java | 4 +- .../deepamehta/core/model/TopicTypeModel.java | 5 +- .../de/deepamehta/core/model/TypeModel.java | 6 +- 10 files changed, 127 insertions(+), 93 deletions(-) diff --git a/modules/dm4-core/src/main/java/de/deepamehta/core/DeepaMehtaObject.java b/modules/dm4-core/src/main/java/de/deepamehta/core/DeepaMehtaObject.java index 3e162a1fe..eca1c159e 100644 --- a/modules/dm4-core/src/main/java/de/deepamehta/core/DeepaMehtaObject.java +++ b/modules/dm4-core/src/main/java/de/deepamehta/core/DeepaMehtaObject.java @@ -51,6 +51,12 @@ public interface DeepaMehtaObject extends Identifiable, JSONEnabled { void setCompositeValue(CompositeValue comp, ClientState clientState, Directives directives); + + + // === Updating === + + ChangeReport update(DeepaMehtaObjectModel model, ClientState clientState, Directives directives); + // --- void updateChildTopic(AssociationDefinition assocDef, TopicModel newChildTopic, ClientState clientState, @@ -121,12 +127,6 @@ Association getAssociation(String assocTypeUri, String myRoleTypeUri, String oth - // === Updating === - - ChangeReport update(DeepaMehtaObjectModel model, ClientState clientState, Directives directives); - - - // === Deletion === /** diff --git a/modules/dm4-core/src/main/java/de/deepamehta/core/Topic.java b/modules/dm4-core/src/main/java/de/deepamehta/core/Topic.java index be9ffc2fd..8a7606ec1 100644 --- a/modules/dm4-core/src/main/java/de/deepamehta/core/Topic.java +++ b/modules/dm4-core/src/main/java/de/deepamehta/core/Topic.java @@ -18,6 +18,8 @@ public interface Topic extends DeepaMehtaObject { TopicModel getModel(); + // === Updating === + ChangeReport update(TopicModel model, ClientState clientState, Directives directives); // === Traversal === diff --git a/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/AttachedType.java b/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/AttachedType.java index 67c8d6a8c..6741f00e8 100644 --- a/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/AttachedType.java +++ b/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/AttachedType.java @@ -200,10 +200,10 @@ public TypeModel getModel() { void fetch(TypeModel model) { setModel(model); // - // 1) init data type - getModel().setDataTypeUri(fetchDataTypeTopic().getUri()); - // 2) init index modes - getModel().setIndexModes(fetchIndexModes()); + // ### 1) init data type + // ### getModel().setDataTypeUri(fetchDataTypeTopic().getUri()); + // ### 2) init index modes + // ### getModel().setIndexModes(fetchIndexModes()); // 3) init association definitions initAssociationDefinitions(); // @@ -262,33 +262,6 @@ void store(ClientState clientState) { // === Fetch === - private RelatedTopicModel fetchDataTypeTopic() { - try { - // Note: the low-level storage call prevents possible endless recursion (caused by POST_FETCH_HOOK). - // Consider the Access Control plugin: loading topic type dm4.accesscontrol.acl_facet would imply - // loading its ACL which in turn would rely on this very topic type. - // ### FIXME: is this still true? The POST_FETCH_HOOK is dropped meanwhile. - RelatedTopicModel dataType = dms.storage.getTopicRelatedTopic(getId(), "dm4.core.aggregation", - "dm4.core.type", null, "dm4.core.data_type"); - if (dataType == null) { - throw new RuntimeException("No data type topic is associated to " + className() + " \"" + - getUri() + "\""); - } - return dataType; - } catch (Exception e) { - throw new RuntimeException("Fetching the data type topic for " + className() + " \"" + - getUri() + "\" failed", e); - } - } - - private Set fetchIndexModes() { - ResultSet topics = getRelatedTopics("dm4.core.aggregation", "dm4.core.type", null, - "dm4.core.index_mode", false, false, 0, null); // fetchComposite=false - return IndexMode.fromTopics(topics.getItems()); - } - - // --- - private void initAssociationDefinitions() { Map assocDefs = fetchAssociationDefinitions(); List sequence = fetchSequence(); @@ -377,7 +350,8 @@ private void fetchViewConfig() { private void storeDataTypeUri() { // remove current assignment - long assocId = fetchDataTypeTopic().getAssociationModel().getId(); + long assocId = dms.objectFactory.fetchDataTypeTopic(getId(), getUri(), className()) + .getAssociationModel().getId(); dms.deleteAssociation(assocId, null); // clientState=null // create new assignment associateDataType(); diff --git a/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/EmbeddedService.java b/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/EmbeddedService.java index ba487f8e9..b40a415ae 100644 --- a/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/EmbeddedService.java +++ b/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/EmbeddedService.java @@ -414,13 +414,13 @@ public Set getTopicTypeUris() { } @Override - public AttachedTopicType getTopicType(String uri, ClientState clientState) { + public TopicType getTopicType(String uri, ClientState clientState) { if (uri == null) { throw new IllegalArgumentException("Tried to get a topic type with null URI"); } DeepaMehtaTransaction tx = beginTx(); try { - AttachedTopicType topicType = typeCache.getTopicType(uri); + TopicType topicType = typeCache.getTopicType(uri); tx.success(); return topicType; } catch (Exception e) { @@ -480,7 +480,7 @@ public Directives updateTopicType(TopicTypeModel model, ClientState clientState) try { // Note: type lookup is by ID. The URI might have changed, the ID does not. String topicTypeUri = getTopic(model.getId(), false, clientState).getUri(); // fetchComposite=false - AttachedTopicType topicType = getTopicType(topicTypeUri, clientState); + TopicType topicType = getTopicType(topicTypeUri, clientState); Directives directives = new Directives(); // topicType.update(model, clientState, directives); @@ -516,13 +516,13 @@ public Set getAssociationTypeUris() { } @Override - public AttachedAssociationType getAssociationType(String uri, ClientState clientState) { + public AssociationType getAssociationType(String uri, ClientState clientState) { if (uri == null) { throw new IllegalArgumentException("Tried to get an association type with null URI"); } DeepaMehtaTransaction tx = beginTx(); try { - AttachedAssociationType assocType = typeCache.getAssociationType(uri); + AssociationType assocType = typeCache.getAssociationType(uri); tx.success(); return assocType; } catch (Exception e) { diff --git a/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/ObjectFactoryImpl.java b/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/ObjectFactoryImpl.java index 9e73ab575..661426cd0 100644 --- a/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/ObjectFactoryImpl.java +++ b/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/ObjectFactoryImpl.java @@ -1,15 +1,24 @@ package de.deepamehta.core.impl.service; import de.deepamehta.core.Association; +import de.deepamehta.core.AssociationType; import de.deepamehta.core.AssociationDefinition; import de.deepamehta.core.RelatedTopic; import de.deepamehta.core.ResultSet; import de.deepamehta.core.Topic; +import de.deepamehta.core.TopicType; import de.deepamehta.core.model.AssociationDefinitionModel; +import de.deepamehta.core.model.AssociationTypeModel; +import de.deepamehta.core.model.IndexMode; import de.deepamehta.core.model.RelatedTopicModel; +import de.deepamehta.core.model.SimpleValue; +import de.deepamehta.core.model.TopicModel; +import de.deepamehta.core.model.TopicTypeModel; import de.deepamehta.core.model.ViewConfigurationModel; import de.deepamehta.core.service.ObjectFactory; +import java.util.Set; + class ObjectFactoryImpl implements ObjectFactory { @@ -136,6 +145,79 @@ public RelatedTopic fetchPartCardinality(Association assoc) { return new AttachedRelatedTopic(model, dms); } + // ----------------------------------------------------------------------------------------- Package Private Methods + + TopicType fetchTopicType(String topicTypeUri) { + TopicModel typeTopic = dms.storage.getTopic("uri", new SimpleValue(topicTypeUri)); + checkTopicType(topicTypeUri, typeTopic); + // + // 1) init data type + String dataTypeUri = fetchDataTypeTopic(typeTopic.getId(), topicTypeUri, "topic type").getUri(); + // 2) init index modes + Set indexModes = fetchIndexModes(typeTopic.getId()); + // + TopicTypeModel topicType = new TopicTypeModel(typeTopic, dataTypeUri, indexModes); + return new AttachedTopicType(topicType, dms); + } + + AssociationType fetchAssociationType(String assocTypeUri) { + TopicModel typeTopic = dms.storage.getTopic("uri", new SimpleValue(assocTypeUri)); + checkAssociationType(assocTypeUri, typeTopic); + // + // 1) init data type + String dataTypeUri = fetchDataTypeTopic(typeTopic.getId(), assocTypeUri, "association type").getUri(); + // 2) init index modes + Set indexModes = fetchIndexModes(typeTopic.getId()); + // ### TODO: to be completed + // + AssociationTypeModel assocType = new AssociationTypeModel(typeTopic, dataTypeUri, indexModes); + return new AttachedAssociationType(assocType, dms); + } + + // --- + + RelatedTopicModel fetchDataTypeTopic(long typeId, String typeUri, String className) { + try { + RelatedTopicModel dataType = dms.storage.getTopicRelatedTopic(typeId, "dm4.core.aggregation", + "dm4.core.type", null, "dm4.core.data_type"); // ### FIXME: null + if (dataType == null) { + throw new RuntimeException("No data type topic is associated to " + className + " \"" + typeUri + "\""); + } + return dataType; + } catch (Exception e) { + throw new RuntimeException("Fetching the data type topic for " + className + " \"" + typeUri + "\" failed", + e); + } + } + + private Set fetchIndexModes(long typeId) { + ResultSet indexModes = dms.storage.getTopicRelatedTopics(typeId, "dm4.core.aggregation", + "dm4.core.type", null, "dm4.core.index_mode", 0); // ### FIXME: null + return IndexMode.fromTopics(indexModes.getItems()); + } + + // --- + + private void checkTopicType(String topicTypeUri, TopicModel typeTopic) { + if (typeTopic == null) { + throw new RuntimeException("Topic type \"" + topicTypeUri + "\" not found"); + } else if (!typeTopic.getTypeUri().equals("dm4.core.topic_type") && + !typeTopic.getTypeUri().equals("dm4.core.meta_type") && + !typeTopic.getTypeUri().equals("dm4.core.meta_meta_type")) { + throw new RuntimeException("URI \"" + topicTypeUri + "\" refers to a \"" + typeTopic.getTypeUri() + + "\" when the caller expects a \"dm4.core.topic_type\""); + } + } + + private void checkAssociationType(String assocTypeUri, TopicModel typeTopic) { + if (typeTopic == null) { + throw new RuntimeException("Association type \"" + assocTypeUri + "\" not found"); + } else if (!typeTopic.getTypeUri().equals("dm4.core.assoc_type")) { + throw new RuntimeException("URI \"" + assocTypeUri + "\" refers to a \"" + typeTopic.getTypeUri() + + "\" when the caller expects a \"dm4.core.assoc_type\""); + } + } + // ------------------------------------------------------------------------------------------------- Private Methods private TopicTypes fetchTopicTypes(Association assoc) { diff --git a/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/TypeCache.java b/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/TypeCache.java index eb835250a..c4ec4b895 100644 --- a/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/TypeCache.java +++ b/modules/dm4-core/src/main/java/de/deepamehta/core/impl/service/TypeCache.java @@ -1,5 +1,7 @@ package de.deepamehta.core.impl.service; +import de.deepamehta.core.TopicType; +import de.deepamehta.core.AssociationType; import de.deepamehta.core.model.TopicModel; import de.deepamehta.core.model.AssociationTypeModel; import de.deepamehta.core.model.SimpleValue; @@ -25,8 +27,8 @@ class TypeCache { // ---------------------------------------------------------------------------------------------- Instance Variables - private Map topicTypes = new HashMap(); // key: topic type URI - private Map assocTypes = new HashMap(); // key: assoc type URI + private Map topicTypes = new HashMap(); // key: topic type URI + private Map assocTypes = new HashMap(); // key: assoc type URI private EmbeddedService dms; @@ -42,8 +44,8 @@ class TypeCache { // ----------------------------------------------------------------------------------------- Package Private Methods - AttachedTopicType getTopicType(String topicTypeUri) { - AttachedTopicType topicType = topicTypes.get(topicTypeUri); + TopicType getTopicType(String topicTypeUri) { + TopicType topicType = topicTypes.get(topicTypeUri); if (topicType == null) { // ### endlessRecursionProtection.check(topicTypeUri); topicType = loadTopicType(topicTypeUri); @@ -51,8 +53,8 @@ AttachedTopicType getTopicType(String topicTypeUri) { return topicType; } - AttachedAssociationType getAssociationType(String assocTypeUri) { - AttachedAssociationType assocType = assocTypes.get(assocTypeUri); + AssociationType getAssociationType(String assocTypeUri) { + AssociationType assocType = assocTypes.get(assocTypeUri); if (assocType == null) { // ### endlessRecursionProtection.check(assocTypeUri); assocType = loadAssociationType(assocTypeUri); @@ -62,11 +64,11 @@ AttachedAssociationType getAssociationType(String assocTypeUri) { // --- - void put(AttachedTopicType topicType) { + void put(TopicType topicType) { topicTypes.put(topicType.getUri(), topicType); } - void put(AttachedAssociationType assocType) { + void put(AssociationType assocType) { assocTypes.put(assocType.getUri(), assocType); } @@ -81,44 +83,14 @@ void invalidate(String topicTypeUri) { // ------------------------------------------------------------------------------------------------- Private Methods - private AttachedTopicType loadTopicType(String topicTypeUri) { + private TopicType loadTopicType(String topicTypeUri) { logger.info("Loading topic type \"" + topicTypeUri + "\""); - // Note: the low-level storage call prevents possible endless recursion (caused by POST_FETCH_HOOK). - // Consider the Access Control plugin: loading topic type dm4.accesscontrol.acl_facet would imply - // loading its ACL which in turn would rely on this very topic type. - // ### FIXME: is this still true? The POST_FETCH_HOOK is dropped meanwhile. - TopicModel typeTopic = dms.storage.getTopic("uri", new SimpleValue(topicTypeUri)); - // error check - if (typeTopic == null) { - throw new RuntimeException("Topic type \"" + topicTypeUri + "\" not found"); - } else if (!typeTopic.getTypeUri().equals("dm4.core.topic_type") && - !typeTopic.getTypeUri().equals("dm4.core.meta_type") && - !typeTopic.getTypeUri().equals("dm4.core.meta_meta_type")) { - throw new RuntimeException("URI \"" + topicTypeUri + "\" refers to a \"" + typeTopic.getTypeUri() + - "\" when the caller expects a \"dm4.core.topic_type\""); - } - // - AttachedTopicType topicType = new AttachedTopicType(dms); - topicType.fetch(new TopicTypeModel(typeTopic)); - // - return topicType; + return dms.objectFactory.fetchTopicType(topicTypeUri); } - private AttachedAssociationType loadAssociationType(String assocTypeUri) { + private AssociationType loadAssociationType(String assocTypeUri) { logger.info("Loading association type \"" + assocTypeUri + "\""); - TopicModel typeTopic = dms.storage.getTopic("uri", new SimpleValue(assocTypeUri)); - // error check - if (typeTopic == null) { - throw new RuntimeException("Association type \"" + assocTypeUri + "\" not found"); - } else if (!typeTopic.getTypeUri().equals("dm4.core.assoc_type")) { - throw new RuntimeException("URI \"" + assocTypeUri + "\" refers to a \"" + typeTopic.getTypeUri() + - "\" when the caller expects a \"dm4.core.assoc_type\""); - } - // - AttachedAssociationType assocType = new AttachedAssociationType(dms); - assocType.fetch(new AssociationTypeModel(typeTopic)); - // - return assocType; + return dms.objectFactory.fetchAssociationType(assocTypeUri); } // --- diff --git a/modules/dm4-core/src/main/java/de/deepamehta/core/model/AssociationTypeModel.java b/modules/dm4-core/src/main/java/de/deepamehta/core/model/AssociationTypeModel.java index 530c47bb3..847047867 100644 --- a/modules/dm4-core/src/main/java/de/deepamehta/core/model/AssociationTypeModel.java +++ b/modules/dm4-core/src/main/java/de/deepamehta/core/model/AssociationTypeModel.java @@ -24,8 +24,9 @@ public AssociationTypeModel(String uri, String value, String dataTypeUri) { super(uri, "dm4.core.assoc_type", new SimpleValue(value), dataTypeUri); } - public AssociationTypeModel(TopicModel model) { - super(model); + // ### TODO: to be completed + public AssociationTypeModel(TopicModel model, String dataTypeUri, Set indexModes) { + super(model, dataTypeUri, indexModes); } public AssociationTypeModel(JSONObject assocTypeModel) { diff --git a/modules/dm4-core/src/main/java/de/deepamehta/core/model/IndexMode.java b/modules/dm4-core/src/main/java/de/deepamehta/core/model/IndexMode.java index 4a0a45c74..d32543a5a 100644 --- a/modules/dm4-core/src/main/java/de/deepamehta/core/model/IndexMode.java +++ b/modules/dm4-core/src/main/java/de/deepamehta/core/model/IndexMode.java @@ -22,9 +22,9 @@ public enum IndexMode { // -------------------------------------------------------------------------------------------------- Public Methods - public static Set fromTopics(Set topics) { + public static Set fromTopics(Set topics) { Set indexModes = new HashSet(); - for (Topic topic : topics) { + for (TopicModel topic : topics) { indexModes.add(fromUri(topic.getUri())); } return indexModes; diff --git a/modules/dm4-core/src/main/java/de/deepamehta/core/model/TopicTypeModel.java b/modules/dm4-core/src/main/java/de/deepamehta/core/model/TopicTypeModel.java index a64fb84ca..8ad9553e3 100644 --- a/modules/dm4-core/src/main/java/de/deepamehta/core/model/TopicTypeModel.java +++ b/modules/dm4-core/src/main/java/de/deepamehta/core/model/TopicTypeModel.java @@ -28,8 +28,9 @@ public TopicTypeModel(String uri, String topicTypeUri, String value, String data super(uri, topicTypeUri, new SimpleValue(value), dataTypeUri); } - public TopicTypeModel(TopicModel model) { - super(model); + // ### TODO: to be completed + public TopicTypeModel(TopicModel model, String dataTypeUri, Set indexModes) { + super(model, dataTypeUri, indexModes); } public TopicTypeModel(TopicTypeModel model) { diff --git a/modules/dm4-core/src/main/java/de/deepamehta/core/model/TypeModel.java b/modules/dm4-core/src/main/java/de/deepamehta/core/model/TypeModel.java index ce40aca65..6678522d2 100644 --- a/modules/dm4-core/src/main/java/de/deepamehta/core/model/TypeModel.java +++ b/modules/dm4-core/src/main/java/de/deepamehta/core/model/TypeModel.java @@ -39,9 +39,11 @@ public TypeModel(String uri, String topicTypeUri, SimpleValue value, String data this.viewConfigModel = new ViewConfigurationModel(); } - public TypeModel(TopicModel model) { + // ### TODO: to be completed + public TypeModel(TopicModel model, String dataTypeUri, Set indexModes) { super(model); - // ### FIXME: initialization + this.dataTypeUri = dataTypeUri; + this.indexModes = indexModes; } public TypeModel(TypeModel model) {