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