@Override @Transactional public NCSComponent addSubcomponent( final String type, final String foreignSource, final String foreignId, final NCSComponent subComponent, final boolean deleteOrphans) { final ComponentIdentifier subComponentId = getIdentifier(subComponent); LogUtils.debugf( this, "addSubcomponent(%s, %s, %s, %s, %s)", type, foreignSource, foreignId, subComponentId, Boolean.valueOf(deleteOrphans)); final NCSComponent component = getComponent(type, foreignSource, foreignId); final ComponentIdentifier id = getIdentifier(component); final ComponentEventQueue ceq = new ComponentEventQueue(); if (component == null) { throw new ObjectRetrievalFailureException( NCSComponent.class, "Unable to locate component with type=" + type + ", foreignSource=" + foreignSource + ", foreignId=" + foreignId); } final NCSComponent updatedSubComponent = addOrUpdateComponents(subComponentId, subComponent, ceq, deleteOrphans); component.addSubcomponent(updatedSubComponent); m_componentDao.update(component); ceq.componentUpdated(id); try { ceq.sendAll(m_eventProxy); } catch (final EventProxyException e) { LogUtils.warnf( this, e, "Component %s added to %s, but an error occured while sending add/delete/update events.", subComponentId, id); } return getComponent(id); }
private void handleOrphanedComponents( final NCSComponent parent, final ComponentIdentifier child, final ComponentEventQueue ceq, final boolean deleteOrphans) { final ComponentIdentifier parentId = getIdentifier(parent); final NCSComponent childComponent = getComponent(child); final Set<ComponentIdentifier> childChildren = getIdentifiers(childComponent.getSubcomponents()); final Set<ComponentIdentifier> childParents = getIdentifiers(childComponent.getParentComponents()); LogUtils.tracef(this, "handleOrphanedComponents: parent: %s", parentId); LogUtils.tracef(this, "handleOrphanedComponents: child: %s", child); LogUtils.tracef(this, "handleOrphanedComponents: child's children: %s", childChildren); LogUtils.tracef(this, "handleOrphanedComponents: child's parents: %s", childParents); if (childParents.size() == 1) { final ComponentIdentifier childParent = childParents.iterator().next(); if (childParent.equals(parentId)) { LogUtils.tracef( this, "handleOrphanedComponents: child (%s) has only one parent (%s) and it's being deleted.", child, childParent); deleteComponent(child, ceq, deleteOrphans); } else { LogUtils.tracef( this, "handleOrphanedComponents: child (%s) has only one parent (%s) but it's not the one we expected. This is weird.", child, childParent); ceq.componentUpdated(childParent); } } else { LogUtils.tracef( this, "handleOrphanedComponents: child (%s) has more than one parent, sending updates for remaining parents.", child); for (final ComponentIdentifier childParent : childParents) { ceq.componentUpdated(childParent); } } }
private ComponentIdentifier getIdentifier(final NCSComponent component) { return new ComponentIdentifier( component.getId(), component.getType(), component.getForeignSource(), component.getForeignId(), component.getName(), component.getDependenciesRequired()); }
private void deleteComponent( final ComponentIdentifier id, final ComponentEventQueue ceq, final boolean deleteOrphans) { final NCSComponent component = getComponent(id); if (component == null) { throw new WebApplicationException(Status.BAD_REQUEST); } final Set<NCSComponent> parentComponents = component.getParentComponents(); final Set<ComponentIdentifier> childrenIdentifiers = getIdentifiers(component.getSubcomponents()); // first, we deal with orphans if (deleteOrphans) { for (final ComponentIdentifier subId : childrenIdentifiers) { handleOrphanedComponents(component, subId, ceq, deleteOrphans); } } // first, we remove this component from each of its parents for (final NCSComponent parent : parentComponents) { parent.getSubcomponents().remove(component); m_componentDao.update(parent); } // then we delete this component component.setSubcomponents(EMPTY_COMPONENT_SET); m_componentDao.delete(component); // and any events or alarms depending on it deleteEvents(id.getForeignSource(), id.getForeignId()); deleteAlarms(id.getForeignSource(), id.getForeignId()); // alert that the component is deleted ceq.componentDeleted(getIdentifier(component)); // then alert about the parents sendUpdateEvents(ceq, getIdentifiers(parentComponents)); }