001 package de.deepamehta.plugins.typeeditor; 002 003 import de.deepamehta.core.Association; 004 import de.deepamehta.core.Topic; 005 import de.deepamehta.core.Type; 006 import de.deepamehta.core.model.AssociationModel; 007 import de.deepamehta.core.model.AssociationDefinitionModel; 008 import de.deepamehta.core.osgi.PluginActivator; 009 import de.deepamehta.core.service.ClientState; 010 import de.deepamehta.core.service.Directive; 011 import de.deepamehta.core.service.Directives; 012 import de.deepamehta.core.service.event.PostDeleteAssociationListener; 013 import de.deepamehta.core.service.event.PostUpdateAssociationListener; 014 015 import java.util.logging.Logger; 016 017 018 019 public class TypeEditorPlugin extends PluginActivator implements PostUpdateAssociationListener, 020 PostDeleteAssociationListener { 021 022 // ---------------------------------------------------------------------------------------------- Instance Variables 023 024 private Logger logger = Logger.getLogger(getClass().getName()); 025 026 // -------------------------------------------------------------------------------------------------- Public Methods 027 028 029 030 // ******************************** 031 // *** Listener Implementations *** 032 // ******************************** 033 034 035 036 @Override 037 public void postUpdateAssociation(Association assoc, AssociationModel oldModel, ClientState clientState, 038 Directives directives) { 039 if (isAssocDef(assoc.getModel())) { 040 if (isAssocDef(oldModel)) { 041 updateAssocDef(assoc, directives); 042 } else { 043 createAssocDef(assoc, directives); 044 } 045 } else if (isAssocDef(oldModel)) { 046 removeAssocDef(assoc, directives); 047 } 048 } 049 050 @Override 051 public void postDeleteAssociation(Association assoc, Directives directives) { 052 if (isAssocDef(assoc.getModel())) { 053 removeAssocDef(assoc, directives); 054 } 055 } 056 057 058 059 // ------------------------------------------------------------------------------------------------- Private Methods 060 061 private void createAssocDef(Association assoc, Directives directives) { 062 Type parentType = fetchParentType(assoc); 063 String childTypeUri = fetchChildType(assoc).getUri(); 064 // Note: the assoc def's ID is already known. Setting it explicitely 065 // prevents the core from creating the underlying association. 066 AssociationDefinitionModel assocDef = new AssociationDefinitionModel( 067 assoc.getId(), assoc.getUri(), assoc.getTypeUri(), 068 parentType.getUri(), childTypeUri, "dm4.core.one", "dm4.core.one", 069 null // viewConfigModel=null 070 ); 071 logger.info("### Adding association definition \"" + childTypeUri + "\" to type \"" + parentType.getUri() + 072 "\" (" + assocDef + ")"); 073 // 074 parentType.addAssocDef(assocDef); 075 // 076 addUpdateTypeDirective(parentType, directives); 077 } 078 079 private void updateAssocDef(Association assoc, Directives directives) { 080 Type parentType = fetchParentType(assoc); 081 AssociationDefinitionModel assocDef = dms.getTypeStorage().fetchAssociationDefinition(assoc); 082 logger.info("### Updating association definition \"" + assocDef.getChildTypeUri() + "\" of type \"" + 083 parentType.getUri() + "\" (" + assocDef + ")"); 084 // 085 parentType.updateAssocDef(assocDef); 086 // 087 addUpdateTypeDirective(parentType, directives); 088 } 089 090 private void removeAssocDef(Association assoc, Directives directives) { 091 Type parentType = fetchParentType(assoc); 092 String childTypeUri = fetchChildType(assoc).getUri(); 093 logger.info("### Removing association definition \"" + childTypeUri + "\" from type \"" + parentType.getUri() + 094 "\""); 095 // 096 parentType.removeAssocDef(childTypeUri); 097 // 098 addUpdateTypeDirective(parentType, directives); 099 } 100 101 102 103 // === Helper === 104 105 private boolean isAssocDef(AssociationModel assoc) { 106 String typeUri = assoc.getTypeUri(); 107 if (!typeUri.equals("dm4.core.aggregation_def") && 108 !typeUri.equals("dm4.core.composition_def")) { 109 return false; 110 } 111 // 112 if (assoc.hasSameRoleTypeUris()) { 113 return false; 114 } 115 // 116 if (assoc.getRoleModel("dm4.core.parent_type") == null || 117 assoc.getRoleModel("dm4.core.child_type") == null) { 118 return false; 119 } 120 // 121 return true; 122 } 123 124 private void addUpdateTypeDirective(Type type, Directives directives) { 125 if (type.getTypeUri().equals("dm4.core.topic_type")) { 126 directives.add(Directive.UPDATE_TOPIC_TYPE, type); 127 } else if (type.getTypeUri().equals("dm4.core.assoc_type")) { 128 directives.add(Directive.UPDATE_ASSOCIATION_TYPE, type); 129 } 130 // Note: no else here as error check already performed in fetchParentType() 131 } 132 133 // --- 134 135 private Type fetchParentType(Association assoc) { 136 Topic type = dms.getTypeStorage().fetchParentType(assoc); 137 String typeUri = type.getTypeUri(); 138 if (typeUri.equals("dm4.core.topic_type")) { 139 return dms.getTopicType(type.getUri()); 140 } else if (typeUri.equals("dm4.core.assoc_type")) { 141 return dms.getAssociationType(type.getUri()); 142 } else { 143 throw new RuntimeException("Invalid association definition: the dm4.core.parent_type " + 144 "player is not a type but of type \"" + typeUri + "\" (" + assoc + ")"); 145 } 146 } 147 148 private Topic fetchChildType(Association assoc) { 149 return dms.getTypeStorage().fetchChildType(assoc); 150 } 151 }