2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.apex.model.basicmodel.concepts;
23 import java.util.List;
25 import java.util.Map.Entry;
26 import java.util.NavigableMap;
28 import java.util.TreeMap;
29 import java.util.TreeSet;
30 import java.util.UUID;
32 import javax.persistence.CascadeType;
33 import javax.persistence.EmbeddedId;
34 import javax.persistence.Entity;
35 import javax.persistence.JoinColumn;
36 import javax.persistence.JoinTable;
37 import javax.persistence.ManyToMany;
38 import javax.persistence.Table;
39 import javax.xml.bind.Unmarshaller;
40 import javax.xml.bind.annotation.XmlAccessType;
41 import javax.xml.bind.annotation.XmlAccessorType;
42 import javax.xml.bind.annotation.XmlElement;
43 import javax.xml.bind.annotation.XmlType;
45 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
46 import org.onap.policy.apex.model.utilities.Assertions;
49 * The Class AxKeyInformation holds a map of the key information for the entire Apex model. All Apex models
50 * {@link AxModel} must have an {@link AxKeyInformation} field. The {@link AxKeyInformation} class implements the helper
51 * methods of the {@link AxConceptGetter} interface to allow {@link AxKeyInfo} instances to be retrieved by calling
52 * methods directly on this class without referencing the contained map.
54 * Validation checks that the key is not null, that the key information map is not empty, that each key and value in the
55 * map is defined, that the key in each map entry matches the key if each entry value, and that no duplicate UUIDs
56 * exist. Each key information entry is then validated individually.
59 @Table(name = "AxKeyInformation")
61 @XmlAccessorType(XmlAccessType.FIELD)
62 @XmlType(name = "AxKeyInformation", namespace = "http://www.onap.org/policy/apex-pdp",
63 propOrder = { "key", "keyInfoMap" })
65 public class AxKeyInformation extends AxConcept implements AxConceptGetter<AxKeyInfo> {
66 private static final long serialVersionUID = -2746380769017043888L;
69 @XmlElement(name = "key", required = true)
70 private AxArtifactKey key;
73 @ManyToMany(cascade = CascadeType.ALL)
75 joinColumns = { @JoinColumn(name = "keyInfoMapName", referencedColumnName = "name"),
76 @JoinColumn(name = "keyInfoMapVersion", referencedColumnName = "version"), },
77 inverseJoinColumns = { @JoinColumn(name = "keyInfoName", referencedColumnName = "name"),
78 @JoinColumn(name = "keyInfoVersion", referencedColumnName = "version") })
79 private Map<AxArtifactKey, AxKeyInfo> keyInfoMap;
83 * The Default Constructor creates this concept with a null key.
85 public AxKeyInformation() {
86 this(new AxArtifactKey());
92 * @param copyConcept the concept to copy from
94 public AxKeyInformation(final AxKeyInformation copyConcept) {
99 * Constructor to create this concept with the specified key.
101 * @param key the key of the concept
103 public AxKeyInformation(final AxArtifactKey key) {
104 this(key, new TreeMap<AxArtifactKey, AxKeyInfo>());
108 * Constructor to create this concept and set all its fields.
110 * @param key the key of the concept
111 * @param keyInfoMap the key info map of the concept
113 public AxKeyInformation(final AxArtifactKey key, final Map<AxArtifactKey, AxKeyInfo> keyInfoMap) {
115 Assertions.argumentNotNull(key, "key may not be null");
116 Assertions.argumentNotNull(keyInfoMap, "keyInfoMap may not be null");
119 this.keyInfoMap = new TreeMap<>();
120 this.keyInfoMap.putAll(keyInfoMap);
124 * When a model is unmarshalled from disk or from the database, the key information map is returned as a raw Hash
125 * Map. This method is called by JAXB after unmarshaling and is used to convert the hash map to a
126 * {@link NavigableMap} so that it will work with the {@link AxConceptGetter} interface.
128 * @param u the unmarshaler that is unmarshaling the model
129 * @param parent the parent object of this object in the unmarshaler
131 public void afterUnmarshal(final Unmarshaller u, final Object parent) {
132 // The map must be navigable to allow name and version searching,
133 // unmarshaling returns a hash map
134 final NavigableMap<AxArtifactKey, AxKeyInfo> navigablekeyInfoMap = new TreeMap<>();
135 navigablekeyInfoMap.putAll(keyInfoMap);
136 keyInfoMap = navigablekeyInfoMap;
140 * This method generates default key information for all keys found in the concept passed in as a parameter that do
141 * not already have key information.
143 * @param concept the concept for which to generate key information
145 public void generateKeyInfo(final AxConcept concept) {
146 for (final AxKey axKey : concept.getKeys()) {
147 if (!(axKey instanceof AxArtifactKey)) {
151 final AxArtifactKey artifactKey = (AxArtifactKey) axKey;
152 if (!keyInfoMap.containsKey(artifactKey)) {
153 final AxKeyInfo keyInfo = new AxKeyInfo(artifactKey);
154 // generate a reproducible UUID
155 keyInfo.setUuid(AxKeyInfo.generateReproducibleUUID(keyInfo.getID() + keyInfo.getDescription()));
156 keyInfoMap.put(artifactKey, keyInfo);
164 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
167 public AxArtifactKey getKey() {
174 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
177 public List<AxKey> getKeys() {
178 final List<AxKey> keyList = key.getKeys();
179 keyList.addAll(keyInfoMap.keySet());
185 * Sets the key of this concept.
187 * @param key the key of this concept
189 public void setKey(final AxArtifactKey key) {
190 Assertions.argumentNotNull(key, "key may not be null");
195 * Gets the key info map of this concept.
197 * @return the key info map of this concept
199 public Map<AxArtifactKey, AxKeyInfo> getKeyInfoMap() {
204 * Sets the key info map of this concept.
206 * @param keyInfoMap the key info map of this concept
208 public void setKeyInfoMap(final Map<AxArtifactKey, AxKeyInfo> keyInfoMap) {
209 Assertions.argumentNotNull(keyInfoMap, "keyInfoMap may not be null");
210 this.keyInfoMap = new TreeMap<>();
211 this.keyInfoMap.putAll(keyInfoMap);
218 * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.basicmodel.concepts.
219 * AxValidationResult)
222 public AxValidationResult validate(final AxValidationResult resultIn) {
223 AxValidationResult result = resultIn;
225 if (key.equals(AxArtifactKey.getNullKey())) {
226 result.addValidationMessage(
227 new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
230 result = key.validate(result);
232 if (keyInfoMap.size() == 0) {
233 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
234 "keyInfoMap may not be empty"));
236 final Set<UUID> uuidSet = new TreeSet<>();
238 for (final Entry<AxArtifactKey, AxKeyInfo> keyInfoEntry : keyInfoMap.entrySet()) {
239 result = validateKeyInfoEntry(keyInfoEntry, uuidSet, result);
247 * Validate an key information entry
249 * @param keyInfoEntry the key information entry
250 * @param uuidSet the set of UUIDs encountered in validation so far, the UUID of this entry is added to the set
251 * @param result the validation result to append to
252 * @return The validation result
254 private AxValidationResult validateKeyInfoEntry(final Entry<AxArtifactKey, AxKeyInfo> keyInfoEntry,
255 final Set<UUID> uuidSet, AxValidationResult result) {
256 if (keyInfoEntry.getKey().equals(AxArtifactKey.getNullKey())) {
257 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
258 "key on keyInfoMap entry " + keyInfoEntry.getKey() + " may not be the null key"));
259 } else if (keyInfoEntry.getValue() == null) {
260 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
261 "value on keyInfoMap entry " + keyInfoEntry.getKey() + " may not be null"));
263 if (!keyInfoEntry.getKey().equals(keyInfoEntry.getValue().getKey())) {
264 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
265 "key on keyInfoMap entry " + keyInfoEntry.getKey() + " does not equal entry key "
266 + keyInfoEntry.getValue().getKey()));
269 result = keyInfoEntry.getValue().validate(result);
271 if (uuidSet.contains(keyInfoEntry.getValue().getUUID())) {
272 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
273 "duplicate UUID found on keyInfoMap entry " + keyInfoEntry.getKey() + ":"
274 + keyInfoEntry.getValue().getUUID()));
276 uuidSet.add(keyInfoEntry.getValue().getUUID());
286 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
289 public void clean() {
291 for (final Entry<AxArtifactKey, AxKeyInfo> keyInfoEntry : keyInfoMap.entrySet()) {
292 keyInfoEntry.getKey().clean();
293 keyInfoEntry.getValue().clean();
300 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
303 public String toString() {
304 final StringBuilder builder = new StringBuilder();
305 builder.append(this.getClass().getSimpleName());
306 builder.append(":(");
307 builder.append("key=");
309 builder.append(",keyInfoMap=");
310 builder.append(keyInfoMap);
312 return builder.toString();
319 * org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.basicmodel.concepts.
323 public AxConcept copyTo(final AxConcept target) {
324 Assertions.argumentNotNull(target, "target may not be null");
326 final Object copyObject = target;
327 Assertions.instanceOf(copyObject, AxKeyInformation.class);
329 final AxKeyInformation copy = ((AxKeyInformation) copyObject);
330 copy.setKey(new AxArtifactKey(key));
331 final Map<AxArtifactKey, AxKeyInfo> newKeyInfoMap = new TreeMap<>();
332 for (final Entry<AxArtifactKey, AxKeyInfo> keyInfoMapEntry : keyInfoMap.entrySet()) {
333 newKeyInfoMap.put(new AxArtifactKey(keyInfoMapEntry.getKey()), new AxKeyInfo(keyInfoMapEntry.getValue()));
335 copy.setKeyInfoMap(newKeyInfoMap);
343 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
346 public int hashCode() {
347 final int prime = 31;
349 result = prime * result + key.hashCode();
350 result = prime * result + keyInfoMap.hashCode();
357 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang. Object)
360 public boolean equals(final Object obj) {
368 if (getClass() != obj.getClass()) {
372 final AxKeyInformation other = (AxKeyInformation) obj;
373 if (!key.equals(other.key)) {
376 return keyInfoMap.equals(other.keyInfoMap);
382 * @see java.lang.Comparable#compareTo(java.lang.Object)
385 public int compareTo(final AxConcept otherObj) {
386 if (otherObj == null) {
389 if (this == otherObj) {
392 if (getClass() != otherObj.getClass()) {
393 return this.hashCode() - otherObj.hashCode();
396 final AxKeyInformation other = (AxKeyInformation) otherObj;
397 if (!key.equals(other.key)) {
398 return key.compareTo(other.key);
400 if (!keyInfoMap.equals(other.keyInfoMap)) {
401 return (keyInfoMap.hashCode() - other.keyInfoMap.hashCode());
411 * org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#get(org.onap.policy.apex.core.basicmodel.concepts.
415 public AxKeyInfo get(final AxArtifactKey conceptKey) {
416 return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).get(conceptKey);
422 * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#get(java.lang. String)
425 public AxKeyInfo get(final String conceptKeyName) {
426 return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).get(conceptKeyName);
432 * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#get(java.lang. String, java.lang.String)
435 public AxKeyInfo get(final String conceptKeyName, final String conceptKeyVersion) {
436 return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).get(conceptKeyName,
443 * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#getAll(java. lang.String)
446 public Set<AxKeyInfo> getAll(final String conceptKeyName) {
447 return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).getAll(conceptKeyName);
453 * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#getAll(java. lang.String, java.lang.String)
456 public Set<AxKeyInfo> getAll(final String conceptKeyName, final String conceptKeyVersion) {
457 return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxKeyInfo>) keyInfoMap).getAll(conceptKeyName,