2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2019 Nordix Foundation.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.apex.model.basicmodel.concepts;
24 import java.util.List;
26 import java.util.Map.Entry;
27 import java.util.NavigableMap;
29 import java.util.TreeMap;
30 import java.util.TreeSet;
31 import java.util.UUID;
33 import javax.persistence.CascadeType;
34 import javax.persistence.EmbeddedId;
35 import javax.persistence.Entity;
36 import javax.persistence.JoinColumn;
37 import javax.persistence.JoinTable;
38 import javax.persistence.ManyToMany;
39 import javax.persistence.Table;
40 import javax.xml.bind.Unmarshaller;
41 import javax.xml.bind.annotation.XmlAccessType;
42 import javax.xml.bind.annotation.XmlAccessorType;
43 import javax.xml.bind.annotation.XmlElement;
44 import javax.xml.bind.annotation.XmlType;
46 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
47 import org.onap.policy.common.utils.validation.Assertions;
50 * The Class AxKeyInformation holds a map of the key information for the entire Apex model. All Apex models
51 * {@link AxModel} must have an {@link AxKeyInformation} field. The {@link AxKeyInformation} class implements the helper
52 * methods of the {@link AxConceptGetter} interface to allow {@link AxKeyInfo} instances to be retrieved by calling
53 * methods directly on this class without referencing the contained map.
55 * <p>Validation checks that the key is not null, that the key information map is not empty, that each key and value in
56 * the map is defined, that the key in each map entry matches the key if each entry value, and that no duplicate UUIDs
57 * exist. Each key information entry is then validated individually.
60 @Table(name = "AxKeyInformation")
62 @XmlAccessorType(XmlAccessType.FIELD)
63 @XmlType(name = "AxKeyInformation", namespace = "http://www.onap.org/policy/apex-pdp",
64 propOrder = { "key", "keyInfoMap" })
66 public class AxKeyInformation extends AxConcept implements AxConceptGetter<AxKeyInfo> {
67 private static final long serialVersionUID = -2746380769017043888L;
70 @XmlElement(name = "key", required = true)
71 private AxArtifactKey key;
74 @ManyToMany(cascade = CascadeType.ALL)
76 joinColumns = { @JoinColumn(name = "keyInfoMapName", referencedColumnName = "name"),
77 @JoinColumn(name = "keyInfoMapVersion", referencedColumnName = "version"), },
78 inverseJoinColumns = { @JoinColumn(name = "keyInfoName", referencedColumnName = "name"),
79 @JoinColumn(name = "keyInfoVersion", referencedColumnName = "version") })
80 private Map<AxArtifactKey, AxKeyInfo> keyInfoMap;
84 * The Default Constructor creates this concept with a null key.
86 public AxKeyInformation() {
87 this(new AxArtifactKey());
93 * @param copyConcept the concept to copy from
95 public AxKeyInformation(final AxKeyInformation copyConcept) {
100 * Constructor to create this concept with the specified key.
102 * @param key the key of the concept
104 public AxKeyInformation(final AxArtifactKey key) {
105 this(key, new TreeMap<AxArtifactKey, AxKeyInfo>());
109 * Constructor to create this concept and set all its fields.
111 * @param key the key of the concept
112 * @param keyInfoMap the key info map of the concept
114 public AxKeyInformation(final AxArtifactKey key, final Map<AxArtifactKey, AxKeyInfo> keyInfoMap) {
116 Assertions.argumentNotNull(key, "key may not be null");
117 Assertions.argumentNotNull(keyInfoMap, "keyInfoMap may not be null");
120 this.keyInfoMap = new TreeMap<>();
121 this.keyInfoMap.putAll(keyInfoMap);
125 * When a model is unmarshalled from disk or from the database, the key information map is returned as a raw Hash
126 * Map. This method is called by JAXB after unmarshaling and is used to convert the hash map to a
127 * {@link NavigableMap} so that it will work with the {@link AxConceptGetter} interface.
129 * @param unmarshaler the unmarshaler that is unmarshaling the model
130 * @param parent the parent object of this object in the unmarshaler
132 public void afterUnmarshal(final Unmarshaller unmarshaler, final Object parent) {
133 // The map must be navigable to allow name and version searching,
134 // unmarshaling returns a hash map
135 final NavigableMap<AxArtifactKey, AxKeyInfo> navigablekeyInfoMap = new TreeMap<>();
136 navigablekeyInfoMap.putAll(keyInfoMap);
137 keyInfoMap = navigablekeyInfoMap;
141 * This method generates default key information for all keys found in the concept passed in as a parameter that do
142 * not already have key information.
144 * @param concept the concept for which to generate key information
146 public void generateKeyInfo(final AxConcept concept) {
147 for (final AxKey axKey : concept.getKeys()) {
148 if (!(axKey instanceof AxArtifactKey)) {
152 final AxArtifactKey artifactKey = (AxArtifactKey) axKey;
153 if (!keyInfoMap.containsKey(artifactKey)) {
154 final AxKeyInfo keyInfo = new AxKeyInfo(artifactKey);
155 // generate a reproducible UUID
156 keyInfo.setUuid(AxKeyInfo.generateReproducibleUuid(keyInfo.getId() + keyInfo.getDescription()));
157 keyInfoMap.put(artifactKey, keyInfo);
165 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
168 public AxArtifactKey getKey() {
175 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
178 public List<AxKey> getKeys() {
179 final List<AxKey> keyList = key.getKeys();
180 keyList.addAll(keyInfoMap.keySet());
186 * Sets the key of this concept.
188 * @param key the key of this concept
190 public void setKey(final AxArtifactKey key) {
191 Assertions.argumentNotNull(key, "key may not be null");
196 * Gets the key info map of this concept.
198 * @return the key info map of this concept
200 public Map<AxArtifactKey, AxKeyInfo> getKeyInfoMap() {
205 * Sets the key info map of this concept.
207 * @param keyInfoMap the key info map of this concept
209 public void setKeyInfoMap(final Map<AxArtifactKey, AxKeyInfo> keyInfoMap) {
210 Assertions.argumentNotNull(keyInfoMap, "keyInfoMap may not be null");
211 this.keyInfoMap = new TreeMap<>();
212 this.keyInfoMap.putAll(keyInfoMap);
219 * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.basicmodel.concepts.
220 * AxValidationResult)
223 public AxValidationResult validate(final AxValidationResult resultIn) {
224 AxValidationResult result = resultIn;
226 if (key.equals(AxArtifactKey.getNullKey())) {
227 result.addValidationMessage(
228 new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
231 result = key.validate(result);
233 if (keyInfoMap.size() == 0) {
234 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
235 "keyInfoMap may not be empty"));
237 final Set<UUID> uuidSet = new TreeSet<>();
239 for (final Entry<AxArtifactKey, AxKeyInfo> keyInfoEntry : keyInfoMap.entrySet()) {
240 result = validateKeyInfoEntry(keyInfoEntry, uuidSet, result);
248 * Validate an key information entry.
250 * @param keyInfoEntry the key information entry
251 * @param uuidSet the set of UUIDs encountered in validation so far, the UUID of this entry is added to the set
252 * @param result the validation result to append to
253 * @return The validation result
255 private AxValidationResult validateKeyInfoEntry(final Entry<AxArtifactKey, AxKeyInfo> keyInfoEntry,
256 final Set<UUID> uuidSet, AxValidationResult result) {
257 if (keyInfoEntry.getKey().equals(AxArtifactKey.getNullKey())) {
258 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
259 "key on keyInfoMap entry " + keyInfoEntry.getKey() + " may not be the null key"));
260 } else if (keyInfoEntry.getValue() == null) {
261 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
262 "value on keyInfoMap entry " + keyInfoEntry.getKey() + " may not be null"));
264 if (!keyInfoEntry.getKey().equals(keyInfoEntry.getValue().getKey())) {
265 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
266 "key on keyInfoMap entry " + keyInfoEntry.getKey() + " does not equal entry key "
267 + keyInfoEntry.getValue().getKey()));
270 result = keyInfoEntry.getValue().validate(result);
272 if (uuidSet.contains(keyInfoEntry.getValue().getUuid())) {
273 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
274 "duplicate UUID found on keyInfoMap entry " + keyInfoEntry.getKey() + ":"
275 + keyInfoEntry.getValue().getUuid()));
277 uuidSet.add(keyInfoEntry.getValue().getUuid());
287 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
290 public void clean() {
292 for (final Entry<AxArtifactKey, AxKeyInfo> keyInfoEntry : keyInfoMap.entrySet()) {
293 keyInfoEntry.getKey().clean();
294 keyInfoEntry.getValue().clean();
301 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
304 public String toString() {
305 final StringBuilder builder = new StringBuilder();
306 builder.append(this.getClass().getSimpleName());
307 builder.append(":(");
308 builder.append("key=");
310 builder.append(",keyInfoMap=");
311 builder.append(keyInfoMap);
313 return builder.toString();
320 * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.basicmodel.concepts.
324 public AxConcept copyTo(final AxConcept target) {
325 Assertions.argumentNotNull(target, "target may not be null");
327 final Object copyObject = target;
328 Assertions.instanceOf(copyObject, AxKeyInformation.class);
330 final AxKeyInformation copy = ((AxKeyInformation) copyObject);
331 copy.setKey(new AxArtifactKey(key));
332 final Map<AxArtifactKey, AxKeyInfo> newKeyInfoMap = new TreeMap<>();
333 for (final Entry<AxArtifactKey, AxKeyInfo> keyInfoMapEntry : keyInfoMap.entrySet()) {
334 newKeyInfoMap.put(new AxArtifactKey(keyInfoMapEntry.getKey()), new AxKeyInfo(keyInfoMapEntry.getValue()));
336 copy.setKeyInfoMap(newKeyInfoMap);
344 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
347 public int hashCode() {
348 final int prime = 31;
350 result = prime * result + key.hashCode();
351 result = prime * result + keyInfoMap.hashCode();
358 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang. Object)
361 public boolean equals(final Object obj) {
369 if (getClass() != obj.getClass()) {
373 final AxKeyInformation other = (AxKeyInformation) obj;
374 if (!key.equals(other.key)) {
377 return keyInfoMap.equals(other.keyInfoMap);
383 * @see java.lang.Comparable#compareTo(java.lang.Object)
386 public int compareTo(final AxConcept otherObj) {
387 if (otherObj == null) {
390 if (this == otherObj) {
393 if (getClass() != otherObj.getClass()) {
394 return this.hashCode() - otherObj.hashCode();
397 final AxKeyInformation other = (AxKeyInformation) otherObj;
398 if (!key.equals(other.key)) {
399 return key.compareTo(other.key);
401 if (!keyInfoMap.equals(other.keyInfoMap)) {
402 return (keyInfoMap.hashCode() - other.keyInfoMap.hashCode());
412 * org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#get(org.onap.policy.apex.core.basicmodel.concepts.
416 public AxKeyInfo get(final AxArtifactKey conceptKey) {
417 return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).get(conceptKey);
423 * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#get(java.lang. String)
426 public AxKeyInfo get(final String conceptKeyName) {
427 return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).get(conceptKeyName);
433 * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#get(java.lang. String, java.lang.String)
436 public AxKeyInfo get(final String conceptKeyName, final String conceptKeyVersion) {
437 return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).get(conceptKeyName,
444 * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#getAll(java. lang.String)
447 public Set<AxKeyInfo> getAll(final String conceptKeyName) {
448 return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).getAll(conceptKeyName);
454 * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#getAll(java. lang.String, java.lang.String)
457 public Set<AxKeyInfo> getAll(final String conceptKeyName, final String conceptKeyVersion) {
458 return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).getAll(conceptKeyName,