001package de.deepamehta.plugins.contacts.migrations; 002 003import de.deepamehta.core.Topic; 004import de.deepamehta.core.model.AssociationDefinitionModel; 005import de.deepamehta.core.model.AssociationTypeModel; 006import de.deepamehta.core.model.ChildTopicsModel; 007import de.deepamehta.core.service.Migration; 008 009import java.util.ArrayList; 010import java.util.List; 011import java.util.logging.Logger; 012 013 014 015/** 016 * Changes Contacts model and converts content. 017 * Runs only in UPDATE mode. 018 * <p> 019 * Part of DM 4.6 020 */ 021public class Migration2 extends Migration { 022 023 // ---------------------------------------------------------------------------------------------- Instance Variables 024 025 private List<Entry> phoneEntries = new ArrayList(); 026 private List<Entry> addressEntries = new ArrayList(); 027 028 private Logger logger = Logger.getLogger(getClass().getName()); 029 030 // -------------------------------------------------------------------------------------------------- Public Methods 031 032 @Override 033 public void run() { 034 logger.info("########## Converting Phone Entry and Address Entry topics"); 035 // 036 // 1) prepare 037 // 038 bufferContentAndDeleteTypes(); 039 // 040 // 2) change model 041 // 042 dms.createAssociationType(new AssociationTypeModel("dm4.contacts.phone_entry", "Phone Entry", 043 "dm4.core.composite") 044 .addAssocDef(new AssociationDefinitionModel("dm4.core.aggregation_def", 045 "dm4.contacts.phone_entry", "dm4.contacts.phone_label", "dm4.core.many", "dm4.core.one"))); 046 dms.createAssociationType(new AssociationTypeModel("dm4.contacts.address_entry", "Address Entry", 047 "dm4.core.composite") 048 .addAssocDef(new AssociationDefinitionModel("dm4.core.aggregation_def", 049 "dm4.contacts.address_entry", "dm4.contacts.address_label", "dm4.core.many", "dm4.core.one"))); 050 dms.getTopicType("dm4.contacts.person") 051 .addAssocDefBefore(new AssociationDefinitionModel("dm4.core.composition_def", "dm4.contacts.phone_entry", 052 "dm4.contacts.person", "dm4.contacts.phone_number", "dm4.core.one", "dm4.core.many"), 053 "dm4.contacts.email_address") 054 .addAssocDefBefore(new AssociationDefinitionModel("dm4.core.composition_def", "dm4.contacts.address_entry", 055 "dm4.contacts.person", "dm4.contacts.address", "dm4.core.one", "dm4.core.many"), 056 "dm4.contacts.notes"); 057 dms.getTopicType("dm4.contacts.institution") 058 .addAssocDefBefore(new AssociationDefinitionModel("dm4.core.composition_def", "dm4.contacts.phone_entry", 059 "dm4.contacts.institution", "dm4.contacts.phone_number", "dm4.core.one", "dm4.core.many"), 060 "dm4.contacts.email_address") 061 .addAssocDefBefore(new AssociationDefinitionModel("dm4.core.composition_def", "dm4.contacts.address_entry", 062 "dm4.contacts.institution", "dm4.contacts.address", "dm4.core.one", "dm4.core.many"), 063 "dm4.contacts.notes"); 064 // 065 // 3) convert content 066 // 067 for (Entry entry : phoneEntries) convertPhoneEntry(entry); 068 for (Entry entry : addressEntries) convertAddressEntry(entry); 069 // 070 logger.info("########## Converting Phone Entry and Address Entry topics complete.\n " + 071 "Phone entries converted: " + phoneEntries.size() + "\n " + 072 "Address entries converted: " + addressEntries.size()); 073 } 074 075 // ------------------------------------------------------------------------------------------------- Private Methods 076 077 private void bufferContentAndDeleteTypes() { 078 // 079 // 1) buffer entry topic content in memory 080 // 081 // Note: the actual conversion (as performed later) relies on the buffered content 082 for (Topic phoneEntry : dms.getTopics("dm4.contacts.phone_entry", 0)) bufferPhoneEntry(phoneEntry); 083 for (Topic addressEntry : dms.getTopics("dm4.contacts.address_entry", 0)) bufferAddressEntry(addressEntry); 084 // 085 // 2) temporarily change entry types 086 // 087 // Note: we change comp_def to aggr_def to avoid deleting childs when deleting the entry topics (next step). 088 // The childs are the Phone and Address topics we want keep and reassign later (while the actual conversion). 089 dms.getTopicType("dm4.contacts.phone_entry").getAssocDef("dm4.contacts.phone_number") 090 .setTypeUri("dm4.core.aggregation_def"); 091 dms.getTopicType("dm4.contacts.address_entry").getAssocDef("dm4.contacts.address") 092 .setTypeUri("dm4.core.aggregation_def"); 093 // 094 // 3) delete entry topics 095 // 096 // Note: deleting the entry types (next step) requires to delete all instances before. 097 for (Entry entry : phoneEntries) entry.topic.delete(); 098 for (Entry entry : addressEntries) entry.topic.delete(); 099 // 100 // 4) delete entry types 101 // 102 // Note: the entry topic types must be deleted as they are recreated as association types with the same URI. 103 dms.deleteTopicType("dm4.contacts.phone_entry"); 104 dms.deleteTopicType("dm4.contacts.address_entry"); 105 } 106 107 // --- 108 109 private void bufferPhoneEntry(Topic phoneEntry) { 110 Topic parent = phoneEntry.getRelatedTopic("dm4.core.composition", "dm4.core.child", "dm4.core.parent", null); 111 Topic phoneLabel = phoneEntry.getChildTopics().getTopic("dm4.contacts.phone_label"); 112 Topic phoneNumber = phoneEntry.getChildTopics().getTopic("dm4.contacts.phone_number"); 113 phoneEntries.add(new Entry(phoneEntry, parent, phoneLabel.getId(), phoneNumber.getId())); 114 } 115 116 private void bufferAddressEntry(Topic addressEntry) { 117 Topic parent = addressEntry.getRelatedTopic("dm4.core.composition", "dm4.core.child", "dm4.core.parent", null); 118 Topic addressLabel = addressEntry.getChildTopics().getTopic("dm4.contacts.address_label"); 119 Topic address = addressEntry.getChildTopics().getTopic("dm4.contacts.address"); 120 addressEntries.add(new Entry(addressEntry, parent, addressLabel.getId(), address.getId())); 121 } 122 123 // --- 124 125 private void convertPhoneEntry(Entry entry) { 126 entry.parent.getChildTopics().addRef("dm4.contacts.phone_number", entry.objectId, new ChildTopicsModel() 127 .putRef("dm4.contacts.phone_label", entry.labelId)); 128 } 129 130 private void convertAddressEntry(Entry entry) { 131 entry.parent.getChildTopics().addRef("dm4.contacts.address", entry.objectId, new ChildTopicsModel() 132 .putRef("dm4.contacts.address_label", entry.labelId)); 133 } 134 135 // --- 136 137 private class Entry { 138 139 private Topic topic; 140 private Topic parent; 141 private long labelId; 142 private long objectId; 143 144 private Entry(Topic topic, Topic parent, long labelId, long objectId) { 145 this.topic = topic; 146 this.parent = parent; 147 this.labelId = labelId; 148 this.objectId = objectId; 149 } 150 } 151}