/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2019 Nordix Foundation.
+ * Copyright (C) 2019-2020 Nordix Foundation.
+ * Modifications Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.function.Function;
import javax.persistence.CascadeType;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
-import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
+import javax.persistence.MappedSuperclass;
import javax.persistence.Table;
import javax.ws.rs.core.Response;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
-import org.onap.policy.common.utils.validation.Assertions;
+import org.apache.commons.lang3.StringUtils;
import org.onap.policy.models.base.PfValidationResult.ValidationResult;
// @formatter:off
* @param C the concept being contained
*/
//@formatter:on
+@MappedSuperclass
@Entity
@Table(name = "PfConceptContainer")
@Data
@EqualsAndHashCode(callSuper = false)
public class PfConceptContainer<C extends PfConcept, A extends PfNameVersion> extends PfConcept
- implements PfConceptGetter<C>, PfAuthorative<List<Map<String, A>>> {
+ implements PfConceptGetter<C>, PfAuthorative<List<Map<String, A>>> {
private static final long serialVersionUID = -324211738823208318L;
@EmbeddedId
private PfConceptKey key;
- @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+ @ManyToMany(cascade = CascadeType.ALL)
+ // @formatter:off
+ @JoinTable(
+ joinColumns = {
+ @JoinColumn(name = "conceptContainerMapName", referencedColumnName = "name"),
+ @JoinColumn(name = "concpetContainerMapVersion", referencedColumnName = "version")
+ },
+ inverseJoinColumns = {
+ @JoinColumn(name = "conceptContainerName", referencedColumnName = "name"),
+ @JoinColumn(name = "conceptContainerVersion", referencedColumnName = "version")
+ }
+ )
+ // @formatter:on
private Map<PfConceptKey, C> conceptMap;
/**
*/
public PfConceptContainer(@NonNull final PfConceptContainer<C, A> copyConcept) {
super(copyConcept);
+ this.key = new PfConceptKey(copyConcept.key);
+
+ this.conceptMap = new TreeMap<>();
+ for (final Entry<PfConceptKey, C> conceptMapEntry : copyConcept.conceptMap.entrySet()) {
+ PfConceptKey newK = new PfConceptKey(conceptMapEntry.getKey());
+ C newC = PfUtils.makeCopy(conceptMapEntry.getValue());
+ this.conceptMap.put(newK, newC);
+ }
}
@Override
public List<Map<String, A>> toAuthorative() {
// The returned list is a list of map singletons with one map for each map
// entry in the concept container
- List<Map<String, A>> toscaPolicyMapList = new ArrayList<>();
+ List<Map<String, A>> toscaConceptMapList = new ArrayList<>();
for (Entry<PfConceptKey, C> conceptEntry : getConceptMap().entrySet()) {
// Create a map to hold this entry
toscaPolicyMap.put(conceptEntry.getKey().getName(), authoritiveImpl.toAuthorative());
// Add the map to the returned list
- toscaPolicyMapList.add(toscaPolicyMap);
+ toscaConceptMapList.add(toscaPolicyMap);
}
- return toscaPolicyMapList;
+ return toscaConceptMapList;
}
@Override
for (Map<String, A> incomingConceptMap : authorativeList) {
// Add the map entries one by one
for (Entry<String, A> incomingConceptEntry : incomingConceptMap.entrySet()) {
- C jpaConcept = getConceptNewInstance();
+ PfConceptKey conceptKey = new PfConceptKey();
+ if (incomingConceptEntry.getKey().matches(PfKey.KEY_ID_REGEXP)) {
+ conceptKey = new PfConceptKey(incomingConceptEntry.getKey());
+ } else {
+ conceptKey.setName(incomingConceptEntry.getKey());
+ if (incomingConceptEntry.getValue().getVersion() != null) {
+ conceptKey.setVersion(incomingConceptEntry.getValue().getVersion());
+ } else {
+ conceptKey.setVersion(PfKey.NULL_KEY_VERSION);
+ }
+ }
+
+ incomingConceptEntry.getValue().setName(findConceptField(conceptKey, conceptKey.getName(),
+ incomingConceptEntry.getValue(), PfNameVersion::getName));
+ incomingConceptEntry.getValue().setVersion(findConceptField(conceptKey, conceptKey.getVersion(),
+ incomingConceptEntry.getValue(), PfNameVersion::getVersion));
+
+ C jpaConcept = getConceptNewInstance();
// This cast allows us to call the fromAuthorative method
@SuppressWarnings("unchecked")
PfAuthorative<A> authoritiveImpl = (PfAuthorative<A>) jpaConcept;
- if (incomingConceptEntry.getValue().getName() == null) {
- incomingConceptEntry.getValue().setName(incomingConceptEntry.getKey());
- }
-
// Set the key name and the rest of the values on the concept
authoritiveImpl.fromAuthorative(incomingConceptEntry.getValue());
- // This cast gets the key of the concept
- PfConceptKey conceptKey = (PfConceptKey) jpaConcept.getKey();
-
- // Set the concept key of the concept
- conceptKey.setName(incomingConceptEntry.getValue().getName());
-
- if (incomingConceptEntry.getValue().getVersion() != null) {
- conceptKey.setVersion(incomingConceptEntry.getValue().getVersion());
- }
- else {
- conceptKey.setVersion(PfKey.NULL_KEY_VERSION);
- }
-
// After all that, save the map entry
conceptMap.put(conceptKey, jpaConcept);
}
if (conceptMap.isEmpty()) {
throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
- "An incoming list of concepts must have at least one entry");
+ "An incoming list of concepts must have at least one entry");
+ }
+ }
+
+ /**
+ * Get an authorative list of the concepts in this container.
+ *
+ * @return the authorative list of concepts
+ */
+ public List<A> toAuthorativeList() {
+ List<A> toscaConceptList = new ArrayList<>();
+
+ for (Map<String, A> toscaConceptMap : toAuthorative()) {
+ toscaConceptList.addAll(toscaConceptMap.values());
}
+
+ return toscaConceptList;
}
@Override
if (key.equals(PfConceptKey.getNullKey())) {
result.addValidationMessage(
- new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
}
result = key.validate(result);
- if (conceptMap.isEmpty()) {
- result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
- "conceptMap may not be empty"));
- } else {
+ if (!conceptMap.isEmpty()) {
result = validateConceptMap(result);
}
for (final Entry<PfConceptKey, C> conceptEntry : conceptMap.entrySet()) {
if (conceptEntry.getKey().equals(PfConceptKey.getNullKey())) {
result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
- "key on concept entry " + conceptEntry.getKey() + " may not be the null key"));
- } else
- if (conceptEntry.getValue() == null) {
- result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
- "value on concept entry " + conceptEntry.getKey() + " may not be null"));
- } else
- if (!conceptEntry.getKey().equals(conceptEntry.getValue().getKey())) {
- result.addValidationMessage(new PfValidationMessage(key, this.getClass(),
- ValidationResult.INVALID, "key on concept entry key " + conceptEntry.getKey()
- + " does not equal concept value key " + conceptEntry.getValue().getKey()));
- result = conceptEntry.getValue().validate(result);
- } else {
- result = conceptEntry.getValue().validate(result);
- }
+ "key on concept entry " + conceptEntry.getKey() + " may not be the null key"));
+ } else if (conceptEntry.getValue() == null) {
+ result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on concept entry " + conceptEntry.getKey() + " may not be null"));
+ } else if (!conceptEntry.getKey().equals(conceptEntry.getValue().getKey())) {
+ result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on concept entry key " + conceptEntry.getKey() + " does not equal concept value key "
+ + conceptEntry.getValue().getKey()));
+ result = conceptEntry.getValue().validate(result);
+ } else {
+ result = conceptEntry.getValue().validate(result);
+ }
}
return result;
}
return 0;
}
- @Override
- public PfConcept copyTo(@NonNull final PfConcept target) {
- Assertions.instanceOf(target, PfConceptContainer.class);
-
- @SuppressWarnings("unchecked")
- final PfConceptContainer<C, A> copy = (PfConceptContainer<C, A>) target;
- copy.setKey(new PfConceptKey(key));
- final Map<PfConceptKey, C> newConceptMap = new TreeMap<>();
- for (final Entry<PfConceptKey, C> conceptMapEntry : conceptMap.entrySet()) {
- C newC = getConceptNewInstance();
- conceptMapEntry.getValue().copyTo(newC);
- newConceptMap.put(new PfConceptKey(conceptMapEntry.getKey()), newC);
+ /**
+ * Get all the concepts that match the given name and version.
+ *
+ * @param conceptKeyName the name of the concept, if null, return all names
+ * @param conceptKeyVersion the version of the concept, if null, return all versions
+ * @return conceptKeyVersion
+ */
+ public Set<C> getAllNamesAndVersions(final String conceptKeyName, final String conceptKeyVersion) {
+ if (conceptKeyName == null || conceptKeyVersion == null || PfKey.NULL_KEY_VERSION.equals(conceptKeyVersion)) {
+ return getAll(conceptKeyName, conceptKeyVersion);
+ } else {
+ final Set<C> returnSet = new TreeSet<>();
+ C foundConcept = get(conceptKeyName, conceptKeyVersion);
+ if (foundConcept != null) {
+ returnSet.add(foundConcept);
+ }
+ return returnSet;
}
- copy.setConceptMap(newConceptMap);
-
- return copy;
}
@Override
public C get(final PfConceptKey conceptKey) {
- return new PfConceptGetterImpl<>((NavigableMap<PfConceptKey, C>) conceptMap).get(conceptKey);
+ if (conceptKey.isNullVersion()) {
+ return get(conceptKey.getName());
+ } else {
+ return new PfConceptGetterImpl<>((NavigableMap<PfConceptKey, C>) conceptMap).get(conceptKey);
+ }
}
@Override
@Override
public C get(final String conceptKeyName, final String conceptKeyVersion) {
return new PfConceptGetterImpl<>((NavigableMap<PfConceptKey, C>) conceptMap).get(conceptKeyName,
- conceptKeyVersion);
+ conceptKeyVersion);
}
@Override
@Override
public Set<C> getAll(final String conceptKeyName, final String conceptKeyVersion) {
return new PfConceptGetterImpl<>((NavigableMap<PfConceptKey, C>) conceptMap).getAll(conceptKeyName,
- conceptKeyVersion);
+ conceptKeyVersion);
}
/**
private C getConceptNewInstance() {
try {
String conceptClassName =
- ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].getTypeName();
- return (C) Class.forName(conceptClassName).newInstance();
+ ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].getTypeName();
+ return (C) Class.forName(conceptClassName).getDeclaredConstructor().newInstance();
} catch (Exception ex) {
throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR,
- "failed to instantiate instance of container concept class", ex);
+ "failed to instantiate instance of container concept class", ex);
+ }
+ }
+
+ private String findConceptField(final PfConceptKey conceptKey, final String keyFieldValue,
+ final PfNameVersion concept, final Function<PfNameVersion, String> fieldGetterFunction) {
+
+ String conceptField = fieldGetterFunction.apply(concept);
+
+ if (StringUtils.isBlank(conceptField) || keyFieldValue.equals(conceptField)) {
+ return keyFieldValue;
+ } else {
+ throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, "Key " + conceptKey.getId() + " field "
+ + keyFieldValue + " does not match the value " + conceptField + " in the concept field");
}
}
}