aboutsummaryrefslogtreecommitdiffstats
path: root/cps-ri/src
diff options
context:
space:
mode:
authordanielhanrahan <daniel.hanrahan@est.tech>2024-11-22 12:17:54 +0000
committerdanielhanrahan <daniel.hanrahan@est.tech>2024-11-25 18:37:20 +0000
commit52896b8ecee8cce64519972f12b7a68351c6c1ad (patch)
tree3d145dfee53fb6bb01fc49ecbad9faa2352340cd /cps-ri/src
parent295495b3f4376f42c5788e89725aef0466a8a578 (diff)
CpsDataPersistenceService refactoring
- Extract common code to reduce duplication. - Move private methods below public methods, and move private static methods to bottom of file. - Note some private methods are left in-place due to checkstyle rules (method overloads belong together). Issue-ID: CPS-2365 Signed-off-by: danielhanrahan <daniel.hanrahan@est.tech> Change-Id: I088a5340e315d55aaf427444bdbfdcadf918464a
Diffstat (limited to 'cps-ri/src')
-rw-r--r--cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java371
1 files changed, 174 insertions, 197 deletions
diff --git a/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java b/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java
index ecbe447226..b7e50815e6 100644
--- a/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java
+++ b/cps-ri/src/main/java/org/onap/cps/ri/CpsDataPersistenceServiceImpl.java
@@ -116,26 +116,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
}
- /**
- * Convert DataNode object into Fragment and places the result in the fragments placeholder. Performs same action
- * for all DataNode children recursively.
- *
- * @param anchorEntity anchorEntity
- * @param dataNodeToBeConverted dataNode
- * @return a Fragment built from current DataNode
- */
- private FragmentEntity convertToFragmentWithAllDescendants(final AnchorEntity anchorEntity,
- final DataNode dataNodeToBeConverted) {
- final FragmentEntity parentFragment = toFragmentEntity(anchorEntity, dataNodeToBeConverted);
- final Builder<FragmentEntity> childFragmentsImmutableSetBuilder = ImmutableSet.builder();
- for (final DataNode childDataNode : dataNodeToBeConverted.getChildDataNodes()) {
- final FragmentEntity childFragment = convertToFragmentWithAllDescendants(anchorEntity, childDataNode);
- childFragmentsImmutableSetBuilder.add(childFragment);
- }
- parentFragment.setChildFragments(childFragmentsImmutableSetBuilder.build());
- return parentFragment;
- }
-
@Override
public void addListElements(final String dataspaceName, final String anchorName, final String parentNodeXpath,
final Collection<DataNode> newListElements) {
@@ -150,53 +130,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
addChildrenDataNodes(anchorEntity, parentNodeXpath, dataNodes);
}
- private void addChildrenDataNodes(final AnchorEntity anchorEntity, final String parentNodeXpath,
- final Collection<DataNode> newChildren) {
- final FragmentEntity parentFragmentEntity = getFragmentEntity(anchorEntity, parentNodeXpath);
- final List<FragmentEntity> fragmentEntities = new ArrayList<>(newChildren.size());
- try {
- for (final DataNode newChildAsDataNode : newChildren) {
- final FragmentEntity newChildAsFragmentEntity =
- convertToFragmentWithAllDescendants(anchorEntity, newChildAsDataNode);
- newChildAsFragmentEntity.setParentId(parentFragmentEntity.getId());
- fragmentEntities.add(newChildAsFragmentEntity);
- }
- fragmentRepository.saveAll(fragmentEntities);
- } catch (final DataIntegrityViolationException dataIntegrityViolationException) {
- log.warn("Exception occurred : {} , While saving : {} children, retrying using individual save operations",
- dataIntegrityViolationException, fragmentEntities.size());
- retrySavingEachChildIndividually(anchorEntity, parentNodeXpath, newChildren);
- }
- }
-
- private void addNewChildDataNode(final AnchorEntity anchorEntity, final String parentNodeXpath,
- final DataNode newChild) {
- final FragmentEntity parentFragmentEntity = getFragmentEntity(anchorEntity, parentNodeXpath);
- final FragmentEntity newChildAsFragmentEntity = convertToFragmentWithAllDescendants(anchorEntity, newChild);
- newChildAsFragmentEntity.setParentId(parentFragmentEntity.getId());
- try {
- fragmentRepository.save(newChildAsFragmentEntity);
- } catch (final DataIntegrityViolationException dataIntegrityViolationException) {
- throw AlreadyDefinedException.forDataNodes(Collections.singletonList(newChild.getXpath()),
- anchorEntity.getName());
- }
- }
-
- private void retrySavingEachChildIndividually(final AnchorEntity anchorEntity, final String parentNodeXpath,
- final Collection<DataNode> newChildren) {
- final Collection<String> failedXpaths = new HashSet<>();
- for (final DataNode newChild : newChildren) {
- try {
- addNewChildDataNode(anchorEntity, parentNodeXpath, newChild);
- } catch (final AlreadyDefinedException alreadyDefinedException) {
- failedXpaths.add(newChild.getXpath());
- }
- }
- if (!failedXpaths.isEmpty()) {
- throw AlreadyDefinedException.forDataNodes(failedXpaths, anchorEntity.getName());
- }
- }
-
@Override
public void batchUpdateDataLeaves(final String dataspaceName, final String anchorName,
final Map<String, Map<String, Serializable>> updatedLeavesPerXPath) {
@@ -246,19 +179,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
}
}
- private void logMissingXPaths(final Collection<String> xpaths, final Collection<FragmentEntity>
- existingFragmentEntities) {
- final Set<String> existingXPaths = existingFragmentEntities.stream().map(FragmentEntity::getXpath)
- .collect(Collectors.toSet());
-
- final Set<String> missingXPaths = xpaths.stream().filter(xpath -> !existingXPaths.contains(xpath))
- .collect(Collectors.toSet());
-
- if (!missingXPaths.isEmpty()) {
- log.warn("Cannot update data nodes: Target XPaths {} not found in DB.", missingXPaths);
- }
- }
-
private void retryUpdateDataNodesIndividually(final AnchorEntity anchorEntity,
final Collection<FragmentEntity> fragmentEntities) {
final Collection<String> failedXpaths = new HashSet<>();
@@ -306,14 +226,8 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
description = "Time taken to query data nodes")
public List<DataNode> queryDataNodes(final String dataspaceName, final String anchorName, final String cpsPath,
final FetchDescendantsOption fetchDescendantsOption) {
- final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
- final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName);
- final CpsPathQuery cpsPathQuery;
- try {
- cpsPathQuery = CpsPathUtil.getCpsPathQuery(cpsPath);
- } catch (final PathParsingException pathParsingException) {
- throw new CpsPathException(pathParsingException.getMessage());
- }
+ final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName);
+ final CpsPathQuery cpsPathQuery = getCpsPathQuery(cpsPath);
Collection<FragmentEntity> fragmentEntities;
fragmentEntities = fragmentRepository.findByAnchorAndCpsPath(anchorEntity, cpsPathQuery);
@@ -321,8 +235,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
final Collection<String> ancestorXpaths = processAncestorXpath(fragmentEntities, cpsPathQuery);
fragmentEntities = fragmentRepository.findByAnchorAndXpathIn(anchorEntity, ancestorXpaths);
}
- fragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption,
- fragmentEntities);
return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities);
}
@@ -333,12 +245,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
final FetchDescendantsOption fetchDescendantsOption,
final PaginationOption paginationOption) {
final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
- final CpsPathQuery cpsPathQuery;
- try {
- cpsPathQuery = CpsPathUtil.getCpsPathQuery(cpsPath);
- } catch (final PathParsingException e) {
- throw new CpsPathException(e.getMessage());
- }
+ final CpsPathQuery cpsPathQuery = getCpsPathQuery(cpsPath);
final List<Long> anchorIds;
if (paginationOption == NO_PAGINATION) {
@@ -359,22 +266,10 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
} else {
fragmentEntities = fragmentRepository.findByAnchorIdsAndXpathIn(anchorIds, ancestorXpaths);
}
-
}
- fragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption,
- fragmentEntities);
return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities);
}
- private List<DataNode> createDataNodesFromFragmentEntities(final FetchDescendantsOption fetchDescendantsOption,
- final Collection<FragmentEntity> fragmentEntities) {
- final List<DataNode> dataNodes = new ArrayList<>(fragmentEntities.size());
- for (final FragmentEntity fragmentEntity : fragmentEntities) {
- dataNodes.add(toDataNode(fragmentEntity, fetchDescendantsOption));
- }
- return Collections.unmodifiableList(dataNodes);
- }
-
@Override
public String startSession() {
return sessionManager.startSession();
@@ -394,41 +289,11 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
@Override
public Integer countAnchorsForDataspaceAndCpsPath(final String dataspaceName, final String cpsPath) {
final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
- final CpsPathQuery cpsPathQuery;
- try {
- cpsPathQuery = CpsPathUtil.getCpsPathQuery(cpsPath);
- } catch (final PathParsingException e) {
- throw new CpsPathException(e.getMessage());
- }
+ final CpsPathQuery cpsPathQuery = getCpsPathQuery(cpsPath);
final List<Long> anchorIdList = getAnchorIdsForPagination(dataspaceEntity, cpsPathQuery, NO_PAGINATION);
return anchorIdList.size();
}
- private DataNode toDataNode(final FragmentEntity fragmentEntity,
- final FetchDescendantsOption fetchDescendantsOption) {
- final List<DataNode> childDataNodes = getChildDataNodes(fragmentEntity, fetchDescendantsOption);
- Map<String, Serializable> leaves = new HashMap<>();
- if (fragmentEntity.getAttributes() != null) {
- leaves = jsonObjectMapper.convertJsonString(fragmentEntity.getAttributes(), Map.class);
- }
- return new DataNodeBuilder()
- .withXpath(fragmentEntity.getXpath())
- .withLeaves(leaves)
- .withDataspace(fragmentEntity.getAnchor().getDataspace().getName())
- .withAnchor(fragmentEntity.getAnchor().getName())
- .withChildDataNodes(childDataNodes).build();
- }
-
- private FragmentEntity toFragmentEntity(final AnchorEntity anchorEntity, final DataNode dataNode) {
- return FragmentEntity.builder()
- .anchor(anchorEntity)
- .xpath(dataNode.getXpath())
- .attributes(jsonObjectMapper.asJsonString(dataNode.getLeaves()))
- .build();
- }
-
-
-
@Override
@Transactional
public void replaceListContent(final String dataspaceName, final String anchorName, final String parentNodeXpath,
@@ -487,18 +352,18 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
final Collection<String> deleteChecklist = getNormalizedXpaths(xpathsToDelete);
final Collection<String> xpathsToExistingContainers =
- fragmentRepository.findAllXpathByAnchorAndXpathIn(anchorEntity, deleteChecklist);
+ fragmentRepository.findAllXpathByAnchorAndXpathIn(anchorEntity, deleteChecklist);
if (onlySupportListDeletion) {
final Collection<String> xpathsToExistingListElements = xpathsToExistingContainers.stream()
- .filter(CpsPathUtil::isPathToListElement).toList();
+ .filter(CpsPathUtil::isPathToListElement).toList();
deleteChecklist.removeAll(xpathsToExistingListElements);
} else {
deleteChecklist.removeAll(xpathsToExistingContainers);
}
final Collection<String> xpathsToExistingLists = deleteChecklist.stream()
- .filter(xpath -> fragmentRepository.existsByAnchorAndXpathStartsWith(anchorEntity, xpath + "["))
- .toList();
+ .filter(xpath -> fragmentRepository.existsByAnchorAndXpathStartsWith(anchorEntity, xpath + "["))
+ .toList();
deleteChecklist.removeAll(xpathsToExistingLists);
if (!deleteChecklist.isEmpty()) {
@@ -531,7 +396,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
final String normalizedXpath = getNormalizedXpath(targetXpath);
try {
deleteDataNodes(dataspaceName, anchorName, Collections.singletonList(normalizedXpath),
- onlySupportListNodeDeletion);
+ onlySupportListNodeDeletion);
} catch (final DataNodeNotFoundExceptionBatch dataNodeNotFoundExceptionBatch) {
throw new DataNodeNotFoundException(dataspaceName, anchorName, targetXpath);
}
@@ -559,18 +424,110 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
final Collection<String> xpaths,
final FetchDescendantsOption fetchDescendantsOption) {
final AnchorEntity anchorEntity = getAnchorEntity(dataspaceName, anchorName);
- Collection<FragmentEntity> fragmentEntities = getFragmentEntities(anchorEntity, xpaths);
- fragmentEntities = fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption,
- fragmentEntities);
+ final Collection<FragmentEntity> fragmentEntities = getFragmentEntities(anchorEntity, xpaths);
return createDataNodesFromFragmentEntities(fetchDescendantsOption, fragmentEntities);
}
+
+ private void addChildrenDataNodes(final AnchorEntity anchorEntity, final String parentNodeXpath,
+ final Collection<DataNode> newChildren) {
+ final FragmentEntity parentFragmentEntity = getFragmentEntity(anchorEntity, parentNodeXpath);
+ final List<FragmentEntity> fragmentEntities = new ArrayList<>(newChildren.size());
+ try {
+ for (final DataNode newChildAsDataNode : newChildren) {
+ final FragmentEntity newChildAsFragmentEntity =
+ convertToFragmentWithAllDescendants(anchorEntity, newChildAsDataNode);
+ newChildAsFragmentEntity.setParentId(parentFragmentEntity.getId());
+ fragmentEntities.add(newChildAsFragmentEntity);
+ }
+ fragmentRepository.saveAll(fragmentEntities);
+ } catch (final DataIntegrityViolationException dataIntegrityViolationException) {
+ log.warn("Exception occurred : {} , While saving : {} children, retrying using individual save operations",
+ dataIntegrityViolationException, fragmentEntities.size());
+ retrySavingEachChildIndividually(anchorEntity, parentNodeXpath, newChildren);
+ }
+ }
+
+ private void addNewChildDataNode(final AnchorEntity anchorEntity, final String parentNodeXpath,
+ final DataNode newChild) {
+ final FragmentEntity parentFragmentEntity = getFragmentEntity(anchorEntity, parentNodeXpath);
+ final FragmentEntity newChildAsFragmentEntity = convertToFragmentWithAllDescendants(anchorEntity, newChild);
+ newChildAsFragmentEntity.setParentId(parentFragmentEntity.getId());
+ try {
+ fragmentRepository.save(newChildAsFragmentEntity);
+ } catch (final DataIntegrityViolationException dataIntegrityViolationException) {
+ throw AlreadyDefinedException.forDataNodes(Collections.singletonList(newChild.getXpath()),
+ anchorEntity.getName());
+ }
+ }
+
+ private void retrySavingEachChildIndividually(final AnchorEntity anchorEntity, final String parentNodeXpath,
+ final Collection<DataNode> newChildren) {
+ final Collection<String> failedXpaths = new HashSet<>();
+ for (final DataNode newChild : newChildren) {
+ try {
+ addNewChildDataNode(anchorEntity, parentNodeXpath, newChild);
+ } catch (final AlreadyDefinedException alreadyDefinedException) {
+ failedXpaths.add(newChild.getXpath());
+ }
+ }
+ if (!failedXpaths.isEmpty()) {
+ throw AlreadyDefinedException.forDataNodes(failedXpaths, anchorEntity.getName());
+ }
+ }
+
+ private FragmentEntity convertToFragmentWithAllDescendants(final AnchorEntity anchorEntity,
+ final DataNode dataNodeToBeConverted) {
+ final FragmentEntity parentFragment = toFragmentEntity(anchorEntity, dataNodeToBeConverted);
+ final Builder<FragmentEntity> childFragmentsImmutableSetBuilder = ImmutableSet.builder();
+ for (final DataNode childDataNode : dataNodeToBeConverted.getChildDataNodes()) {
+ final FragmentEntity childFragment = convertToFragmentWithAllDescendants(anchorEntity, childDataNode);
+ childFragmentsImmutableSetBuilder.add(childFragment);
+ }
+ parentFragment.setChildFragments(childFragmentsImmutableSetBuilder.build());
+ return parentFragment;
+ }
+
+ private FragmentEntity toFragmentEntity(final AnchorEntity anchorEntity, final DataNode dataNode) {
+ return FragmentEntity.builder()
+ .anchor(anchorEntity)
+ .xpath(dataNode.getXpath())
+ .attributes(jsonObjectMapper.asJsonString(dataNode.getLeaves()))
+ .build();
+ }
+
+ private List<DataNode> createDataNodesFromFragmentEntities(final FetchDescendantsOption fetchDescendantsOption,
+ final Collection<FragmentEntity> fragmentEntities) {
+ final Collection<FragmentEntity> fragmentEntitiesWithDescendants =
+ fragmentRepository.prefetchDescendantsOfFragmentEntities(fetchDescendantsOption, fragmentEntities);
+ final List<DataNode> dataNodes = new ArrayList<>(fragmentEntitiesWithDescendants.size());
+ for (final FragmentEntity fragmentEntity : fragmentEntitiesWithDescendants) {
+ dataNodes.add(toDataNode(fragmentEntity, fetchDescendantsOption));
+ }
+ return Collections.unmodifiableList(dataNodes);
+ }
+
+ private DataNode toDataNode(final FragmentEntity fragmentEntity,
+ final FetchDescendantsOption fetchDescendantsOption) {
+ final List<DataNode> childDataNodes = getChildDataNodes(fragmentEntity, fetchDescendantsOption);
+ Map<String, Serializable> leaves = new HashMap<>();
+ if (fragmentEntity.getAttributes() != null) {
+ leaves = jsonObjectMapper.convertJsonString(fragmentEntity.getAttributes(), Map.class);
+ }
+ return new DataNodeBuilder()
+ .withXpath(fragmentEntity.getXpath())
+ .withLeaves(leaves)
+ .withDataspace(fragmentEntity.getAnchor().getDataspace().getName())
+ .withAnchor(fragmentEntity.getAnchor().getName())
+ .withChildDataNodes(childDataNodes).build();
+ }
+
private List<DataNode> getChildDataNodes(final FragmentEntity fragmentEntity,
final FetchDescendantsOption fetchDescendantsOption) {
if (fetchDescendantsOption.hasNext()) {
return fragmentEntity.getChildFragments().stream()
.map(childFragmentEntity -> toDataNode(childFragmentEntity, fetchDescendantsOption.next()))
- .collect(Collectors.toList());
+ .toList();
}
return Collections.emptyList();
}
@@ -585,29 +542,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return fragmentRepository.findAnchorIdsForPagination(dataspaceEntity, cpsPathQuery, paginationOption);
}
- private static String getNormalizedXpath(final String xpathSource) {
- if (isRootXpath(xpathSource)) {
- return xpathSource;
- }
- try {
- return CpsPathUtil.getNormalizedXpath(xpathSource);
- } catch (final PathParsingException pathParsingException) {
- throw new CpsPathException(pathParsingException.getMessage());
- }
- }
-
- private static Collection<String> getNormalizedXpaths(final Collection<String> xpaths) {
- final Collection<String> normalizedXpaths = new HashSet<>(xpaths.size());
- for (final String xpath : xpaths) {
- try {
- normalizedXpaths.add(getNormalizedXpath(xpath));
- } catch (final CpsPathException cpsPathException) {
- log.warn("Error parsing xpath \"{}\": {}", xpath, cpsPathException.getMessage());
- }
- }
- return normalizedXpaths;
- }
-
private FragmentEntity getFragmentEntity(final AnchorEntity anchorEntity, final String xpath) {
final FragmentEntity fragmentEntity;
if (isRootXpath(xpath)) {
@@ -628,7 +562,7 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
final boolean haveRootXpath = normalizedXpaths.removeIf(CpsDataPersistenceServiceImpl::isRootXpath);
final List<FragmentEntity> fragmentEntities = fragmentRepository.findByAnchorAndXpathIn(anchorEntity,
- normalizedXpaths);
+ normalizedXpaths);
for (final FragmentEntity fragmentEntity : fragmentEntities) {
normalizedXpaths.remove(fragmentEntity.getXpath());
@@ -647,15 +581,6 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return fragmentEntities;
}
- private static String getListElementXpathPrefix(final Collection<DataNode> newListElements) {
- if (newListElements.isEmpty()) {
- throw new CpsAdminException("Invalid list replacement",
- "Cannot replace list elements with empty collection");
- }
- final String firstChildNodeXpath = newListElements.iterator().next().getXpath();
- return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf('[') + 1);
- }
-
private FragmentEntity getFragmentForReplacement(final FragmentEntity parentEntity,
final DataNode newListElement,
final FragmentEntity existingListElementEntity) {
@@ -671,6 +596,28 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return existingListElementEntity;
}
+ private String mergeLeaves(final Map<String, Serializable> updateLeaves, final String currentLeavesAsString) {
+ Map<String, Serializable> currentLeavesAsMap = new HashMap<>();
+ if (currentLeavesAsString != null) {
+ currentLeavesAsMap = jsonObjectMapper.convertJsonString(currentLeavesAsString, Map.class);
+ currentLeavesAsMap.putAll(updateLeaves);
+ }
+
+ if (currentLeavesAsMap.isEmpty()) {
+ return "";
+ }
+ return jsonObjectMapper.asJsonString(currentLeavesAsMap);
+ }
+
+ private void copyAttributesFromNewDataNode(final FragmentEntity existingFragmentEntity,
+ final DataNode newDataNode) {
+ final String oldOrderedLeavesAsJson = getOrderedLeavesAsJson(existingFragmentEntity.getAttributes());
+ final String newOrderedLeavesAsJson = getOrderedLeavesAsJson(newDataNode.getLeaves());
+ if (!oldOrderedLeavesAsJson.equals(newOrderedLeavesAsJson)) {
+ existingFragmentEntity.setAttributes(jsonObjectMapper.asJsonString(newDataNode.getLeaves()));
+ }
+ }
+
private String getOrderedLeavesAsJson(final Map<String, Serializable> currentLeaves) {
final Map<String, Serializable> sortedLeaves = new TreeMap<>(String::compareTo);
sortedLeaves.putAll(currentLeaves);
@@ -686,6 +633,38 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return jsonObjectMapper.asJsonString(sortedLeaves);
}
+ private static String getNormalizedXpath(final String xpathSource) {
+ if (isRootXpath(xpathSource)) {
+ return xpathSource;
+ }
+ try {
+ return CpsPathUtil.getNormalizedXpath(xpathSource);
+ } catch (final PathParsingException pathParsingException) {
+ throw new CpsPathException(pathParsingException.getMessage());
+ }
+ }
+
+ private static Collection<String> getNormalizedXpaths(final Collection<String> xpaths) {
+ final Collection<String> normalizedXpaths = new HashSet<>(xpaths.size());
+ for (final String xpath : xpaths) {
+ try {
+ normalizedXpaths.add(getNormalizedXpath(xpath));
+ } catch (final CpsPathException cpsPathException) {
+ log.warn("Error parsing xpath \"{}\": {}", xpath, cpsPathException.getMessage());
+ }
+ }
+ return normalizedXpaths;
+ }
+
+ private static String getListElementXpathPrefix(final Collection<DataNode> newListElements) {
+ if (newListElements.isEmpty()) {
+ throw new CpsAdminException("Invalid list replacement",
+ "Cannot replace list elements with empty collection");
+ }
+ final String firstChildNodeXpath = newListElements.iterator().next().getXpath();
+ return firstChildNodeXpath.substring(0, firstChildNodeXpath.lastIndexOf('[') + 1);
+ }
+
private static Map<String, FragmentEntity> extractListElementFragmentEntitiesByXPath(
final Set<FragmentEntity> childEntities, final String listElementXpathPrefix) {
return childEntities.stream()
@@ -717,25 +696,23 @@ public class CpsDataPersistenceServiceImpl implements CpsDataPersistenceService
return !existingListElementsByXpath.containsKey(replacementDataNode.getXpath());
}
- private void copyAttributesFromNewDataNode(final FragmentEntity existingFragmentEntity,
- final DataNode newDataNode) {
- final String oldOrderedLeavesAsJson = getOrderedLeavesAsJson(existingFragmentEntity.getAttributes());
- final String newOrderedLeavesAsJson = getOrderedLeavesAsJson(newDataNode.getLeaves());
- if (!oldOrderedLeavesAsJson.equals(newOrderedLeavesAsJson)) {
- existingFragmentEntity.setAttributes(jsonObjectMapper.asJsonString(newDataNode.getLeaves()));
+ private static CpsPathQuery getCpsPathQuery(final String cpsPath) {
+ try {
+ return CpsPathUtil.getCpsPathQuery(cpsPath);
+ } catch (final PathParsingException e) {
+ throw new CpsPathException(e.getMessage());
}
}
- private String mergeLeaves(final Map<String, Serializable> updateLeaves, final String currentLeavesAsString) {
- Map<String, Serializable> currentLeavesAsMap = new HashMap<>();
- if (currentLeavesAsString != null) {
- currentLeavesAsMap = jsonObjectMapper.convertJsonString(currentLeavesAsString, Map.class);
- currentLeavesAsMap.putAll(updateLeaves);
- }
-
- if (currentLeavesAsMap.isEmpty()) {
- return "";
+ private static void logMissingXPaths(final Collection<String> xpaths,
+ final Collection<FragmentEntity> existingFragmentEntities) {
+ final Set<String> existingXPaths =
+ existingFragmentEntities.stream().map(FragmentEntity::getXpath).collect(Collectors.toSet());
+ final Set<String> missingXPaths =
+ xpaths.stream().filter(xpath -> !existingXPaths.contains(xpath)).collect(Collectors.toSet());
+ if (!missingXPaths.isEmpty()) {
+ log.warn("Cannot update data nodes: Target XPaths {} not found in DB.", missingXPaths);
}
- return jsonObjectMapper.asJsonString(currentLeavesAsMap);
}
+
}