Skip to content

Commit

Permalink
Core: refactor type construction pt.1 (#340).
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jri committed Oct 20, 2012
1 parent af31a96 commit 3bbd5d6
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 93 deletions.
Expand Up @@ -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,
Expand Down Expand Up @@ -121,12 +127,6 @@ Association getAssociation(String assocTypeUri, String myRoleTypeUri, String oth



// === Updating ===

ChangeReport update(DeepaMehtaObjectModel model, ClientState clientState, Directives directives);



// === Deletion ===

/**
Expand Down
2 changes: 2 additions & 0 deletions modules/dm4-core/src/main/java/de/deepamehta/core/Topic.java
Expand Up @@ -18,6 +18,8 @@ public interface Topic extends DeepaMehtaObject {

TopicModel getModel();

// === Updating ===

ChangeReport update(TopicModel model, ClientState clientState, Directives directives);

// === Traversal ===
Expand Down
Expand Up @@ -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();
//
Expand Down Expand Up @@ -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<IndexMode> fetchIndexModes() {
ResultSet<RelatedTopic> 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<Long, AssociationDefinition> assocDefs = fetchAssociationDefinitions();
List<RelatedAssociation> sequence = fetchSequence();
Expand Down Expand Up @@ -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();
Expand Down
Expand Up @@ -414,13 +414,13 @@ public Set<String> 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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -516,13 +516,13 @@ public Set<String> 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) {
Expand Down
@@ -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 {
Expand Down Expand Up @@ -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<IndexMode> 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<IndexMode> 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<IndexMode> fetchIndexModes(long typeId) {
ResultSet<RelatedTopicModel> 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) {
Expand Down
@@ -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;
Expand All @@ -25,8 +27,8 @@ class TypeCache {

// ---------------------------------------------------------------------------------------------- Instance Variables

private Map<String, AttachedTopicType> topicTypes = new HashMap(); // key: topic type URI
private Map<String, AttachedAssociationType> assocTypes = new HashMap(); // key: assoc type URI
private Map<String, TopicType> topicTypes = new HashMap(); // key: topic type URI
private Map<String, AssociationType> assocTypes = new HashMap(); // key: assoc type URI

private EmbeddedService dms;

Expand All @@ -42,17 +44,17 @@ 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);
}
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);
Expand All @@ -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);
}

Expand All @@ -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);
}

// ---
Expand Down
Expand Up @@ -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<IndexMode> indexModes) {
super(model, dataTypeUri, indexModes);
}

public AssociationTypeModel(JSONObject assocTypeModel) {
Expand Down
Expand Up @@ -22,9 +22,9 @@ public enum IndexMode {

// -------------------------------------------------------------------------------------------------- Public Methods

public static Set<IndexMode> fromTopics(Set<RelatedTopic> topics) {
public static Set<IndexMode> fromTopics(Set<RelatedTopicModel> topics) {
Set<IndexMode> indexModes = new HashSet();
for (Topic topic : topics) {
for (TopicModel topic : topics) {
indexModes.add(fromUri(topic.getUri()));
}
return indexModes;
Expand Down
Expand Up @@ -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<IndexMode> indexModes) {
super(model, dataTypeUri, indexModes);
}

public TopicTypeModel(TopicTypeModel model) {
Expand Down
Expand Up @@ -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<IndexMode> indexModes) {
super(model);
// ### FIXME: initialization
this.dataTypeUri = dataTypeUri;
this.indexModes = indexModes;
}

public TypeModel(TypeModel model) {
Expand Down

0 comments on commit 3bbd5d6

Please sign in to comment.