d6a7efb7101751f162a25aa0e67adf27bbcda190
[policy/apex-pdp.git] / model / policy-model / src / main / java / org / onap / policy / apex / model / policymodel / concepts / AxPolicies.java
1 /*-
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.model.policymodel.concepts;
23
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Map.Entry;
27 import java.util.NavigableMap;
28 import java.util.Set;
29 import java.util.TreeMap;
30
31 import javax.persistence.CascadeType;
32 import javax.persistence.EmbeddedId;
33 import javax.persistence.Entity;
34 import javax.persistence.JoinColumn;
35 import javax.persistence.JoinTable;
36 import javax.persistence.ManyToMany;
37 import javax.persistence.Table;
38 import javax.xml.bind.Unmarshaller;
39 import javax.xml.bind.annotation.XmlAccessType;
40 import javax.xml.bind.annotation.XmlAccessorType;
41 import javax.xml.bind.annotation.XmlElement;
42 import javax.xml.bind.annotation.XmlType;
43
44 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
45 import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
46 import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter;
47 import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetterImpl;
48 import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
49 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
50 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
51 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
52 import org.onap.policy.common.utils.validation.Assertions;
53
54 /**
55  * This class is a policy container and holds a map of the policies for an entire Apex model. All Apex models that use
56  * policies must have an {@link AxPolicies} field. The {@link AxPolicies} class implements the helper methods of the
57  * {@link AxConceptGetter} interface to allow {@link AxPolicy} instances to be retrieved by calling methods directly on
58  * this class without referencing the contained map.
59  *
60  * <p>Validation checks that the container key is not null. An error is issued if no policies are defined in the
61  * container. Each policy entry is checked to ensure that its key and value are not null and that the key matches the
62  * key in the map value. Each policy entry is then validated individually.
63  */
64 @Entity
65 @Table(name = "AxPolicies")
66
67 @XmlAccessorType(XmlAccessType.FIELD)
68 @XmlType(name = "AxPolicies", namespace = "http://www.onap.org/policy/apex-pdp", propOrder =
69     { "key", "policyMap" })
70
71 public class AxPolicies extends AxConcept implements AxConceptGetter<AxPolicy> {
72     private static final long serialVersionUID = 4290442590545820316L;
73
74     @EmbeddedId
75     @XmlElement(name = "key", required = true)
76     private AxArtifactKey key;
77
78     // @formatter:off
79     @ManyToMany(cascade = CascadeType.ALL)
80     @JoinTable(
81             joinColumns = {@JoinColumn(name = "policyMapName", referencedColumnName = "name"),
82                     @JoinColumn(name = "policyMapVersion", referencedColumnName = "version")},
83             inverseJoinColumns = {@JoinColumn(name = "policyName", referencedColumnName = "name"),
84                     @JoinColumn(name = "policyVersion", referencedColumnName = "version")})
85     @XmlElement(required = true)
86     private Map<AxArtifactKey, AxPolicy> policyMap;
87     // @formatter:on
88
89     /**
90      * The Default Constructor creates a {@link AxPolicies} object with a null artifact key and creates an empty event
91      * map.
92      */
93     public AxPolicies() {
94         this(new AxArtifactKey());
95     }
96
97     /**
98      * The Key Constructor creates a {@link AxPolicies} object with the given artifact key and creates an empty event
99      * map.
100      *
101      * @param key the key
102      */
103     public AxPolicies(final AxArtifactKey key) {
104         this(key, new TreeMap<AxArtifactKey, AxPolicy>());
105     }
106
107     /**
108      * Copy constructor.
109      *
110      * @param copyConcept the concept to copy from
111      */
112     public AxPolicies(final AxPolicies copyConcept) {
113         super(copyConcept);
114     }
115
116     /**
117      * This Constructor creates a policy container with all of its fields defined.
118      *
119      * @param key the policy container key
120      * @param policyMap the policies to be stored in the policy container
121      */
122     public AxPolicies(final AxArtifactKey key, final Map<AxArtifactKey, AxPolicy> policyMap) {
123         super();
124         Assertions.argumentNotNull(key, "key may not be null");
125         Assertions.argumentNotNull(policyMap, "policyMap may not be null");
126
127         this.key = key;
128         this.policyMap = new TreeMap<>();
129         this.policyMap.putAll(policyMap);
130     }
131
132     /**
133      * When a model is unmarshalled from disk or from the database, the policy map is returned as a raw hash map. This
134      * method is called by JAXB after unmarshaling and is used to convert the hash map to a {@link NavigableMap} so that
135      * it will work with the {@link AxConceptGetter} interface.
136      *
137      * @param unmarshaler the unmarshaler that is unmarshaling the model
138      * @param parent the parent object of this object in the unmarshaler
139      */
140     public void afterUnmarshal(final Unmarshaller unmarshaler, final Object parent) {
141         // The map must be navigable to allow name and version searching, unmarshaling returns a
142         // hash map
143         final NavigableMap<AxArtifactKey, AxPolicy> navigablePolicyMap = new TreeMap<>();
144         navigablePolicyMap.putAll(policyMap);
145         policyMap = navigablePolicyMap;
146     }
147
148     /**
149      * {@inheritDoc}.
150      */
151     @Override
152     public AxArtifactKey getKey() {
153         return key;
154     }
155
156     /**
157      * {@inheritDoc}.
158      */
159     @Override
160     public List<AxKey> getKeys() {
161         final List<AxKey> keyList = key.getKeys();
162
163         for (final AxPolicy policy : policyMap.values()) {
164             keyList.addAll(policy.getKeys());
165         }
166
167         return keyList;
168     }
169
170     /**
171      * Sets the key of the policy container.
172      *
173      * @param key the policy container key
174      */
175     public void setKey(final AxArtifactKey key) {
176         Assertions.argumentNotNull(key, "key may not be null");
177         this.key = key;
178     }
179
180     /**
181      * Gets the policy map containing all policies in the policy container.
182      *
183      * @return the policy map with all the policies in the container
184      */
185     public Map<AxArtifactKey, AxPolicy> getPolicyMap() {
186         return policyMap;
187     }
188
189     /**
190      * Sets the policy map containing all policies in the policy container.
191      *
192      * @param policyMap the policy map with all the policies to be put in the container
193      */
194     public void setPolicyMap(final Map<AxArtifactKey, AxPolicy> policyMap) {
195         Assertions.argumentNotNull(policyMap, "policyMap may not be null");
196         this.policyMap = new TreeMap<>();
197         this.policyMap.putAll(policyMap);
198     }
199
200     /**
201      * {@inheritDoc}.
202      */
203     @Override
204     public AxValidationResult validate(final AxValidationResult resultIn) {
205         AxValidationResult result = resultIn;
206
207         if (key.equals(AxArtifactKey.getNullKey())) {
208             result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
209                             "key is a null key"));
210         }
211
212         result = key.validate(result);
213
214         if (policyMap.size() == 0) {
215             result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
216                             "policyMap may not be empty"));
217         } else {
218             for (final Entry<AxArtifactKey, AxPolicy> policyEntry : policyMap.entrySet()) {
219                 final AxArtifactKey entryKey = policyEntry.getKey();
220                 if (entryKey.equals(AxArtifactKey.getNullKey())) {
221                     result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
222                                     "key on policy entry " + entryKey + " may not be the null key"));
223                 } else if (policyEntry.getValue() == null) {
224                     result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
225                                     "value on policy entry " + entryKey + " may not be null"));
226                 } else {
227                     validate(result, policyEntry, entryKey);
228                     result = policyEntry.getValue().validate(result);
229                 }
230             }
231         }
232
233         return result;
234     }
235
236     private void validate(final AxValidationResult result, final Entry<AxArtifactKey, AxPolicy> policyEntry,
237                     final AxArtifactKey entryKey) {
238         if (!entryKey.equals(policyEntry.getValue().getKey())) {
239             result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
240                             "key on policy entry key " + entryKey + " does not equal policy value key "
241                                             + policyEntry.getValue().getKey()));
242         }
243     }
244
245     /**
246      * {@inheritDoc}.
247      */
248     @Override
249     public void clean() {
250         key.clean();
251         for (final Entry<AxArtifactKey, AxPolicy> policyEntry : policyMap.entrySet()) {
252             policyEntry.getKey().clean();
253             policyEntry.getValue().clean();
254         }
255     }
256
257     /**
258      * {@inheritDoc}.
259      */
260     @Override
261     public String toString() {
262         final StringBuilder builder = new StringBuilder();
263         builder.append(this.getClass().getSimpleName());
264         builder.append(":(");
265         builder.append("key=");
266         builder.append(key);
267         builder.append(",policyMap=");
268         builder.append(policyMap);
269         builder.append(")");
270         return builder.toString();
271     }
272
273     /**
274      * {@inheritDoc}.
275      */
276     @Override
277     public AxConcept copyTo(final AxConcept targetObject) {
278         Assertions.argumentNotNull(targetObject, "target may not be null");
279
280         final Object copyObject = targetObject;
281         Assertions.instanceOf(copyObject, AxPolicies.class);
282
283         final AxPolicies copy = ((AxPolicies) copyObject);
284         copy.setKey(new AxArtifactKey(key));
285
286         final Map<AxArtifactKey, AxPolicy> newPolicyMap = new TreeMap<>();
287         for (final Entry<AxArtifactKey, AxPolicy> policyMapEntry : policyMap.entrySet()) {
288             newPolicyMap.put(new AxArtifactKey(policyMapEntry.getKey()), new AxPolicy(policyMapEntry.getValue()));
289         }
290         copy.setPolicyMap(newPolicyMap);
291
292         return copy;
293     }
294
295     /**
296      * {@inheritDoc}.
297      */
298     @Override
299     public int hashCode() {
300         final int prime = 31;
301         int result = 1;
302         result = prime * result + key.hashCode();
303         result = prime * result + policyMap.hashCode();
304         return result;
305     }
306
307     /**
308      * {@inheritDoc}.
309      */
310     @Override
311     public boolean equals(final Object obj) {
312         if (obj == null) {
313             return false;
314         }
315         if (this == obj) {
316             return true;
317         }
318
319         if (getClass() != obj.getClass()) {
320             return false;
321         }
322
323         final AxPolicies other = (AxPolicies) obj;
324         if (!key.equals(other.key)) {
325             return false;
326         }
327         return policyMap.equals(other.policyMap);
328     }
329
330     /**
331      * {@inheritDoc}.
332      */
333     @Override
334     public int compareTo(final AxConcept otherObj) {
335         if (otherObj == null) {
336             return -1;
337         }
338         if (this == otherObj) {
339             return 0;
340         }
341         if (getClass() != otherObj.getClass()) {
342             return this.hashCode() - otherObj.hashCode();
343         }
344
345         final AxPolicies other = (AxPolicies) otherObj;
346         if (!key.equals(other.key)) {
347             return key.compareTo(other.key);
348         }
349         if (!policyMap.equals(other.policyMap)) {
350             return (policyMap.hashCode() - other.policyMap.hashCode());
351         }
352
353         return 0;
354     }
355
356     /**
357      * {@inheritDoc}.
358      */
359     @Override
360     public AxPolicy get(final AxArtifactKey conceptKey) {
361         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).get(conceptKey);
362     }
363
364     /**
365      * {@inheritDoc}.
366      */
367     @Override
368     public AxPolicy get(final String conceptKeyName) {
369         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).get(conceptKeyName);
370     }
371
372     /**
373      * {@inheritDoc}.
374      */
375     @Override
376     public AxPolicy get(final String conceptKeyName, final String conceptKeyVersion) {
377         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).get(conceptKeyName,
378                         conceptKeyVersion);
379     }
380
381     /**
382      * {@inheritDoc}.
383      */
384     @Override
385     public Set<AxPolicy> getAll(final String conceptKeyName) {
386         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).getAll(conceptKeyName);
387     }
388
389     /**
390      * {@inheritDoc}.
391      */
392     @Override
393     public Set<AxPolicy> getAll(final String conceptKeyName, final String conceptKeyVersion) {
394         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxPolicy>) policyMap).getAll(conceptKeyName,
395                         conceptKeyVersion);
396     }
397 }