- public void replaceDataNodeTree(final String dataspaceName, final String anchorName, final DataNode dataNode) {
- final FragmentEntity fragmentEntity = getFragmentByXpath(dataspaceName, anchorName, dataNode.getXpath());
- removeExistingDescendants(fragmentEntity);
-
- fragmentEntity.setAttributes(GSON.toJson(dataNode.getLeaves()));
- final Set<FragmentEntity> childFragmentEntities = dataNode.getChildDataNodes().stream().map(
- childDataNode -> convertToFragmentWithAllDescendants(
- fragmentEntity.getDataspace(), fragmentEntity.getAnchor(), childDataNode)
+ public void replaceDataNodeTree(final String dataspaceName, final String anchorName,
+ final DataNode dataNode) {
+ final var fragmentEntity = getFragmentByXpath(dataspaceName, anchorName, dataNode.getXpath());
+ replaceDataNodeTree(fragmentEntity, dataNode);
+ try {
+ fragmentRepository.save(fragmentEntity);
+ } catch (final StaleStateException staleStateException) {
+ throw new ConcurrencyException("Concurrent Transactions",
+ String.format("dataspace :'%s', Anchor : '%s' and xpath: '%s' is updated by another transaction.",
+ dataspaceName, anchorName, dataNode.getXpath()),
+ staleStateException);
+ }
+ }
+
+ private void replaceDataNodeTree(final FragmentEntity existingFragmentEntity, final DataNode submittedDataNode) {
+
+ existingFragmentEntity.setAttributes(GSON.toJson(submittedDataNode.getLeaves()));
+
+ final Map<String, FragmentEntity> existingChildrenByXpath = existingFragmentEntity.getChildFragments()
+ .stream().collect(Collectors.toMap(FragmentEntity::getXpath, childFragmentEntity -> childFragmentEntity));
+
+ final var updatedChildFragments = new HashSet<FragmentEntity>();
+
+ for (final DataNode submittedChildDataNode : submittedDataNode.getChildDataNodes()) {
+ final FragmentEntity childFragment;
+ if (existingChildrenByXpath.containsKey(submittedChildDataNode.getXpath())) {
+ childFragment = existingChildrenByXpath.get(submittedChildDataNode.getXpath());
+ replaceDataNodeTree(childFragment, submittedChildDataNode);
+ } else {
+ childFragment = convertToFragmentWithAllDescendants(
+ existingFragmentEntity.getDataspace(), existingFragmentEntity.getAnchor(), submittedChildDataNode);
+ }
+ updatedChildFragments.add(childFragment);
+ }
+ existingFragmentEntity.setChildFragments(updatedChildFragments);
+ }
+
+ @Override
+ @Transactional
+ public void replaceListDataNodes(final String dataspaceName, final String anchorName, final String parentNodeXpath,
+ final Collection<DataNode> dataNodes) {
+ final var parentEntity = getFragmentByXpath(dataspaceName, anchorName, parentNodeXpath);
+ final var firstChildNodeXpath = dataNodes.iterator().next().getXpath();
+ final var listNodeXpath = firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf("["));
+ removeListNodeDescendants(parentEntity, listNodeXpath);
+ final Set<FragmentEntity> childFragmentEntities = dataNodes.stream().map(
+ dataNode -> convertToFragmentWithAllDescendants(
+ parentEntity.getDataspace(), parentEntity.getAnchor(), dataNode)