package de.deepamehta.contacts.migrations;
import de.deepamehta.core.Topic;
import de.deepamehta.core.model.AssociationDefinitionModel;
import de.deepamehta.core.model.AssociationTypeModel;
import de.deepamehta.core.model.ChildTopicsModel;
import de.deepamehta.core.service.Migration;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
* Changes Contacts model and converts content.
* Runs only in UPDATE mode.
* <p>
* Part of DM 4.6
*/
public class Migration2 extends Migration {
// ---------------------------------------------------------------------------------------------- Instance Variables
private List<Entry> phoneEntries = new ArrayList();
private List<Entry> addressEntries = new ArrayList();
private Logger logger = Logger.getLogger(getClass().getName());
// -------------------------------------------------------------------------------------------------- Public Methods
@Override
public void run() {
logger.info("########## Converting Phone Entry and Address Entry topics");
//
// 1) prepare
//
bufferContentAndDeleteTypes();
//
// 2) change model
//
dm4.createAssociationType(mf.newAssociationTypeModel("dm4.contacts.phone_entry", "Phone Entry",
"dm4.core.composite")
.addAssocDef(mf.newAssociationDefinitionModel("dm4.core.aggregation_def",
"dm4.contacts.phone_entry", "dm4.contacts.phone_label", "dm4.core.many", "dm4.core.one")));
dm4.createAssociationType(mf.newAssociationTypeModel("dm4.contacts.address_entry", "Address Entry",
"dm4.core.composite")
.addAssocDef(mf.newAssociationDefinitionModel("dm4.core.aggregation_def",
"dm4.contacts.address_entry", "dm4.contacts.address_label", "dm4.core.many", "dm4.core.one")));
dm4.getTopicType("dm4.contacts.person")
.addAssocDefBefore(
mf.newAssociationDefinitionModel("dm4.core.composition_def", "dm4.contacts.phone_entry", false,
"dm4.contacts.person", "dm4.contacts.phone_number", "dm4.core.one", "dm4.core.many"),
"dm4.contacts.email_address")
.addAssocDefBefore(
mf.newAssociationDefinitionModel("dm4.core.composition_def", "dm4.contacts.address_entry", false,
"dm4.contacts.person", "dm4.contacts.address", "dm4.core.one", "dm4.core.many"),
"dm4.contacts.notes");
dm4.getTopicType("dm4.contacts.institution")
.addAssocDefBefore(
mf.newAssociationDefinitionModel("dm4.core.composition_def", "dm4.contacts.phone_entry", false,
"dm4.contacts.institution", "dm4.contacts.phone_number", "dm4.core.one", "dm4.core.many"),
"dm4.contacts.email_address")
.addAssocDefBefore(
mf.newAssociationDefinitionModel("dm4.core.composition_def", "dm4.contacts.address_entry", false,
"dm4.contacts.institution", "dm4.contacts.address", "dm4.core.one", "dm4.core.many"),
"dm4.contacts.notes");
//
// 3) convert content
//
for (Entry entry : phoneEntries) convertPhoneEntry(entry);
for (Entry entry : addressEntries) convertAddressEntry(entry);
//
logger.info("########## Converting Phone Entry and Address Entry topics complete\n " +
"Phone entries converted: " + phoneEntries.size() + "\n " +
"Address entries converted: " + addressEntries.size());
}
// ------------------------------------------------------------------------------------------------- Private Methods
private void bufferContentAndDeleteTypes() {
//
// 1) buffer entry topic content in memory
//
// Note: the actual conversion (as performed later) relies on the buffered content
for (Topic phoneEntry : dm4.getTopicsByType("dm4.contacts.phone_entry")) bufferPhoneEntry(phoneEntry);
for (Topic addressEntry : dm4.getTopicsByType("dm4.contacts.address_entry")) bufferAddressEntry(addressEntry);
//
// 2) temporarily change entry types
//
// Note: we change comp_def to aggr_def to avoid deleting childs when deleting the entry topics (next step).
// The childs are the Phone and Address topics we want keep and reassign later (while the actual conversion).
dm4.getTopicType("dm4.contacts.phone_entry").getAssocDef("dm4.contacts.phone_number")
.setTypeUri("dm4.core.aggregation_def");
dm4.getTopicType("dm4.contacts.address_entry").getAssocDef("dm4.contacts.address")
.setTypeUri("dm4.core.aggregation_def");
//
// 3) delete entry topics
//
// Note: deleting the entry types (next step) requires to delete all instances before.
for (Entry entry : phoneEntries) entry.topic.delete();
for (Entry entry : addressEntries) entry.topic.delete();
//
// 4) delete entry types
//
// Note: the entry topic types must be deleted as they are recreated as association types with the same URI.
dm4.deleteTopicType("dm4.contacts.phone_entry");
dm4.deleteTopicType("dm4.contacts.address_entry");
}
// ---
private void bufferPhoneEntry(Topic phoneEntry) {
Topic parent = phoneEntry.getRelatedTopic("dm4.core.composition", "dm4.core.child", "dm4.core.parent", null);
Topic phoneLabel = phoneEntry.getChildTopics().getTopic("dm4.contacts.phone_label");
Topic phoneNumber = phoneEntry.getChildTopics().getTopic("dm4.contacts.phone_number");
phoneEntries.add(new Entry(phoneEntry, parent, phoneLabel.getId(), phoneNumber.getId()));
}
private void bufferAddressEntry(Topic addressEntry) {
Topic parent = addressEntry.getRelatedTopic("dm4.core.composition", "dm4.core.child", "dm4.core.parent", null);
Topic addressLabel = addressEntry.getChildTopics().getTopic("dm4.contacts.address_label");
Topic address = addressEntry.getChildTopics().getTopic("dm4.contacts.address");
addressEntries.add(new Entry(addressEntry, parent, addressLabel.getId(), address.getId()));
}
// ---
private void convertPhoneEntry(Entry entry) {
entry.parent.getChildTopics().addRef("dm4.contacts.phone_number", entry.objectId, mf.newChildTopicsModel()
.putRef("dm4.contacts.phone_label", entry.labelId));
}
private void convertAddressEntry(Entry entry) {
entry.parent.getChildTopics().addRef("dm4.contacts.address", entry.objectId, mf.newChildTopicsModel()
.putRef("dm4.contacts.address_label", entry.labelId));
}
// ---
private class Entry {
private Topic topic;
private Topic parent;
private long labelId;
private long objectId;
private Entry(Topic topic, Topic parent, long labelId, long objectId) {
this.topic = topic;
this.parent = parent;
this.labelId = labelId;
this.objectId = objectId;
}
}
}