/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation.
+ * Copyright (C) 2021-2022 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.onap.cps.spi.repository;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import javax.transaction.Transactional;
+import lombok.RequiredArgsConstructor;
import org.onap.cps.cpspath.parser.CpsPathPrefixType;
import org.onap.cps.cpspath.parser.CpsPathQuery;
import org.onap.cps.spi.entities.FragmentEntity;
+import org.onap.cps.utils.JsonObjectMapper;
+@RequiredArgsConstructor
public class FragmentRepositoryCpsPathQueryImpl implements FragmentRepositoryCpsPathQuery {
- public static final String SIMILAR_TO_ABSOLUTE_PATH_PREFIX = "%/";
- public static final String SIMILAR_TO_OPTIONAL_LIST_INDEX_POSTFIX = "(\\[[^/]*])?";
+ public static final String REGEX_ABSOLUTE_PATH_PREFIX = ".*\\/";
+ public static final String REGEX_OPTIONAL_LIST_INDEX_POSTFIX = "(\\[@(?!.*\\[).*?])?$";
@PersistenceContext
private EntityManager entityManager;
-
- private static final Gson GSON = new GsonBuilder().create();
+ private final JsonObjectMapper jsonObjectMapper;
@Override
+ @Transactional
public List<FragmentEntity> findByAnchorAndCpsPath(final int anchorId, final CpsPathQuery cpsPathQuery) {
- final var sqlStringBuilder = new StringBuilder("SELECT * FROM FRAGMENT WHERE anchor_id = :anchorId");
+ final StringBuilder sqlStringBuilder = new StringBuilder("SELECT * FROM FRAGMENT WHERE anchor_id = :anchorId");
final Map<String, Object> queryParameters = new HashMap<>();
queryParameters.put("anchorId", anchorId);
- sqlStringBuilder.append(" AND xpath SIMILAR TO :xpathRegex");
- final String xpathRegex = getSimilarToXpathSqlRegex(cpsPathQuery);
+ sqlStringBuilder.append(" AND xpath ~ :xpathRegex");
+ final String xpathRegex = getXpathSqlRegex(cpsPathQuery);
queryParameters.put("xpathRegex", xpathRegex);
if (cpsPathQuery.hasLeafConditions()) {
sqlStringBuilder.append(" AND attributes @> :leafDataAsJson\\:\\:jsonb");
- queryParameters.put("leafDataAsJson", GSON.toJson(cpsPathQuery.getLeavesData()));
+ queryParameters.put("leafDataAsJson", jsonObjectMapper.asJsonString(
+ cpsPathQuery.getLeavesData()));
}
addTextFunctionCondition(cpsPathQuery, sqlStringBuilder, queryParameters);
- final var query = entityManager.createNativeQuery(sqlStringBuilder.toString(), FragmentEntity.class);
+ final Query query = entityManager.createNativeQuery(sqlStringBuilder.toString(), FragmentEntity.class);
setQueryParameters(query, queryParameters);
- return query.getResultList();
+ return getFragmentEntitiesAsStream(query);
+ }
+
+ private List<FragmentEntity> getFragmentEntitiesAsStream(final Query query) {
+ final List<FragmentEntity> fragmentEntities = new ArrayList<>();
+ query.getResultStream().forEach(fragmentEntity -> {
+ fragmentEntities.add((FragmentEntity) fragmentEntity);
+ entityManager.detach(fragmentEntity);
+ });
+
+ return fragmentEntities;
}
- @NotNull
- private static String getSimilarToXpathSqlRegex(final CpsPathQuery cpsPathQuery) {
- final var xpathRegexBuilder = new StringBuilder();
+ private static String getXpathSqlRegex(final CpsPathQuery cpsPathQuery) {
+ final StringBuilder xpathRegexBuilder = new StringBuilder();
if (CpsPathPrefixType.ABSOLUTE.equals(cpsPathQuery.getCpsPathPrefixType())) {
xpathRegexBuilder.append(escapeXpath(cpsPathQuery.getXpathPrefix()));
} else {
- xpathRegexBuilder.append(SIMILAR_TO_ABSOLUTE_PATH_PREFIX);
+ xpathRegexBuilder.append(REGEX_ABSOLUTE_PATH_PREFIX);
xpathRegexBuilder.append(escapeXpath(cpsPathQuery.getDescendantName()));
}
- xpathRegexBuilder.append(SIMILAR_TO_OPTIONAL_LIST_INDEX_POSTFIX);
+ xpathRegexBuilder.append(REGEX_OPTIONAL_LIST_INDEX_POSTFIX);
return xpathRegexBuilder.toString();
}
- @NotNull
private static String escapeXpath(final String xpath) {
// See https://jira.onap.org/browse/CPS-500 for limitations of this basic escape mechanism
return xpath.replace("[@", "\\[@");
}
- @Nullable
private static Integer getTextValueAsInt(final CpsPathQuery cpsPathQuery) {
try {
return Integer.parseInt(cpsPathQuery.getTextFunctionConditionValue());
.append(" OR attributes @> jsonb_build_object(:textLeafName, json_build_array(:textValue))");
queryParameters.put("textLeafName", cpsPathQuery.getTextFunctionConditionLeafName());
queryParameters.put("textValue", cpsPathQuery.getTextFunctionConditionValue());
- final var textValueAsInt = getTextValueAsInt(cpsPathQuery);
+ final Integer textValueAsInt = getTextValueAsInt(cpsPathQuery);
if (textValueAsInt != null) {
sqlStringBuilder.append(" OR attributes @> jsonb_build_object(:textLeafName, :textValueAsInt)");
sqlStringBuilder