+
+ private static FragmentEntity toFragmentEntity(final DataspaceEntity dataspaceEntity,
+ final AnchorEntity anchorEntity, final DataNode dataNode) {
+ return FragmentEntity.builder()
+ .dataspace(dataspaceEntity)
+ .anchor(anchorEntity)
+ .xpath(dataNode.getXpath())
+ .attributes(GSON.toJson(dataNode.getLeaves()))
+ .build();
+ }
+
+ @Override
+ public DataNode getDataNode(final String dataspaceName, final String anchorName, final String xpath,
+ final FetchDescendantsOption fetchDescendantsOption) {
+ final FragmentEntity fragmentEntity = getFragmentByXpath(dataspaceName, anchorName, xpath);
+ return toDataNode(fragmentEntity, fetchDescendantsOption);
+ }
+
+ private FragmentEntity getFragmentByXpath(final String dataspaceName, final String anchorName,
+ final String xpath) {
+ final DataspaceEntity dataspaceEntity = dataspaceRepository.getByName(dataspaceName);
+ final AnchorEntity anchorEntity = anchorRepository.getByDataspaceAndName(dataspaceEntity, anchorName);
+ return fragmentRepository.getByDataspaceAndAnchorAndXpath(dataspaceEntity, anchorEntity, xpath);
+ }
+
+ @Override
+ 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 = CpsPathQuery.createFrom(cpsPath);
+ final List<FragmentEntity> fragmentEntities;
+ if (CpsPathQueryType.XPATH_LEAF_VALUE.equals(cpsPathQuery.getCpsPathQueryType())) {
+ fragmentEntities = fragmentRepository
+ .getByAnchorAndXpathAndLeafAttributes(anchorEntity.getId(), cpsPathQuery.getXpathPrefix(), cpsPathQuery
+ .getLeafName(), cpsPathQuery.getLeafValue());
+ } else {
+ fragmentEntities = fragmentRepository
+ .getByAnchorAndEndsWithXpath(anchorEntity.getId(), cpsPathQuery.getEndsWith());
+ }
+ return fragmentEntities.stream()
+ .map(fragmentEntity -> toDataNode(fragmentEntity, fetchDescendantsOption))
+ .collect(Collectors.toUnmodifiableList());
+ }
+
+ private static DataNode toDataNode(final FragmentEntity fragmentEntity,
+ final FetchDescendantsOption fetchDescendantsOption) {
+ final Map<String, Object> leaves = GSON.fromJson(fragmentEntity.getAttributes(), Map.class);
+ final List<DataNode> childDataNodes = getChildDataNodes(fragmentEntity, fetchDescendantsOption);
+ return new DataNodeBuilder()
+ .withXpath(fragmentEntity.getXpath())
+ .withLeaves(leaves)
+ .withChildDataNodes(childDataNodes).build();
+ }
+
+ private static List<DataNode> getChildDataNodes(final FragmentEntity fragmentEntity,
+ final FetchDescendantsOption fetchDescendantsOption) {
+ if (fetchDescendantsOption == INCLUDE_ALL_DESCENDANTS) {
+ return fragmentEntity.getChildFragments().stream()
+ .map(childFragmentEntity -> toDataNode(childFragmentEntity, fetchDescendantsOption))
+ .collect(Collectors.toUnmodifiableList());
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public void updateDataLeaves(final String dataspaceName, final String anchorName, final String xpath,
+ final Map<String, Object> leaves) {
+ final FragmentEntity fragmentEntity = getFragmentByXpath(dataspaceName, anchorName, xpath);
+ fragmentEntity.setAttributes(GSON.toJson(leaves));
+ fragmentRepository.save(fragmentEntity);
+ }
+
+ @Override
+ 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)
+ ).collect(Collectors.toUnmodifiableSet());
+ fragmentEntity.setChildFragments(childFragmentEntities);
+
+ fragmentRepository.save(fragmentEntity);
+ }
+
+ private void removeExistingDescendants(final FragmentEntity fragmentEntity) {
+ fragmentEntity.setChildFragments(Collections.emptySet());
+ fragmentRepository.save(fragmentEntity);
+ }