public ConfigurationDefinitionUpdateReport updateConfigurationDefinition( ConfigurationDefinition newDefinition, ConfigurationDefinition existingDefinition) { ConfigurationDefinitionUpdateReport updateReport = new ConfigurationDefinitionUpdateReport(existingDefinition); /* * handle grouped and ungrouped properties separately. for ungrouped, we don't need to care about the group, but * for the grouped ones we need to start at group level and then look at the properties. This is done below. * * First look at the ungrouped ones. */ List<PropertyDefinition> existingPropertyDefinitions = existingDefinition.getNonGroupedProperties(); List<PropertyDefinition> newPropertyDefinitions = newDefinition.getNonGroupedProperties(); if (existingPropertyDefinitions != null) { for (PropertyDefinition newProperty : newPropertyDefinitions) { PropertyDefinition existingProp = existingDefinition.get(newProperty.getName()); if (existingProp != null) { log.debug("Updating nonGrouped property [" + existingProp + "]"); updatePropertyDefinition(existingProp, newProperty); updateReport.addUpdatedPropertyDefinition(newProperty); } else { log.debug("Adding nonGrouped property [" + newProperty + "]"); existingDefinition.put(newProperty); updateReport.addNewPropertyDefinition(newProperty); } } existingDefinition = removeNoLongerUsedProperties( newDefinition, existingDefinition, existingPropertyDefinitions); } else { // TODO what if existingDefinitions is null? // we probably don't run in here, as the initial persisting is done // somewhere else. } /* * Now update / delete contained groups We need to be careful here, as groups are present in PropertyDefinition * as "backlink" from PropertyDefinition to group */ List<PropertyGroupDefinition> existingGroups = existingDefinition.getGroupDefinitions(); List<PropertyGroupDefinition> newGroups = newDefinition.getGroupDefinitions(); List<PropertyGroupDefinition> toPersist = missingInFirstList(existingGroups, newGroups); List<PropertyGroupDefinition> toDelete = missingInFirstList(newGroups, existingGroups); List<PropertyGroupDefinition> toUpdate = intersection(existingGroups, newGroups); // delete groups no longer present for (PropertyGroupDefinition group : toDelete) { List<PropertyDefinition> groupedDefinitions = existingDefinition.getPropertiesInGroup(group.getName()); // first look for contained stuff for (PropertyDefinition def : groupedDefinitions) { log.debug("Removing property [" + def + "] from group [" + group + "]"); existingPropertyDefinitions.remove(def); existingDefinition.getPropertyDefinitions().remove(def.getName()); def.setPropertyGroupDefinition(null); entityManager.remove(def); } // then remove the definition itself log.debug("Removing group [" + group + "]"); existingGroups.remove(group); entityManager.remove(group); } // update existing groups that stay for (PropertyGroupDefinition group : toUpdate) { String groupName = group.getName(); List<PropertyDefinition> newGroupedDefinitions = newDefinition.getPropertiesInGroup(groupName); for (PropertyDefinition nDef : newGroupedDefinitions) { PropertyDefinition existingProperty = existingDefinition.getPropertyDefinitions().get(nDef.getName()); if (existingProperty != null) { log.debug("Updating property [" + nDef + "] in group [" + group + "]"); updatePropertyDefinition(existingProperty, nDef); updateReport.addUpdatedPropertyDefinition(nDef); } else { log.debug("Adding property [" + nDef + "] to group [" + group + "]"); existingDefinition.put(nDef); updateReport.addNewPropertyDefinition(nDef); } } // delete outdated properties of this group existingDefinition = removeNoLongerUsedProperties( newDefinition, existingDefinition, existingDefinition.getPropertiesInGroup(groupName)); } // persist new groups for (PropertyGroupDefinition group : toPersist) { // First persist a new group definition and then link the properties to it log.debug("Persisting new group [" + group + "]"); entityManager.persist(group); existingGroups.add(group); // iterating over this does not update the underlying crap List<PropertyDefinition> defs = newDefinition.getPropertiesInGroup(group.getName()); Map<String, PropertyDefinition> exPDefs = existingDefinition.getPropertyDefinitions(); for (PropertyDefinition def : defs) { entityManager.persist(def); def.setPropertyGroupDefinition(group); def.setConfigurationDefinition(existingDefinition); if (!exPDefs.containsKey(def.getName())) { updateReport.addNewPropertyDefinition(def); } exPDefs.put(def.getName(), def); } } /* * Now work on the templates. */ Map<String, ConfigurationTemplate> existingTemplates = existingDefinition.getTemplates(); Map<String, ConfigurationTemplate> newTemplates = newDefinition.getTemplates(); List<String> toRemove = new ArrayList<String>(); List<String> templatesToUpdate = new ArrayList<String>(); for (String name : existingTemplates.keySet()) { if (newTemplates.containsKey(name)) { templatesToUpdate.add(name); } else { toRemove.add(name); } } for (String name : toRemove) { log.debug("Removing template [" + name + "]"); ConfigurationTemplate template = existingTemplates.remove(name); entityManager.remove(template); } for (String name : templatesToUpdate) { log.debug("Updating template [" + name + "]"); updateTemplate(existingDefinition.getTemplate(name), newTemplates.get(name)); } for (String name : newTemplates.keySet()) { // add completely new templates if (!existingTemplates.containsKey(name)) { log.debug("Adding template [" + name + "]"); ConfigurationTemplate newTemplate = newTemplates.get(name); // we need to set a valid configurationDefinition, where we will live on. newTemplate.setConfigurationDefinition(existingDefinition); entityManager.persist(newTemplate); existingTemplates.put(name, newTemplate); } } return updateReport; }