2b31aa425fafba019d2a9c02659071ef0c7c3c06
[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.ManyToMany;
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 schema container and holds a map of the context schemas for an entire Apex model. All Apex
55  * models that use context schemas must have an {@link AxContextSchemas} field. The {@link AxContextSchemas} class
56  * implements the helper methods of the {@link AxConceptGetter} interface to allow {@link AxContextSchema} instances to
57  * be retrieved by calling methods directly on this class without referencing the contained map.
58  * 
59  * <p>Validation checks that the container key is not null. An error is issued if no context schemas are defined in the
60  * container. Each context schema entry is checked to ensure that its key and value are not null and that the key
61  * matches the key in the map value. Each context schema entry is then validated individually.
62  */
63 @Entity
64 @Table(name = "AxContextSchemas")
65
66 @XmlAccessorType(XmlAccessType.FIELD)
67 @XmlType(name = "AxContextSchemas", namespace = "http://www.onap.org/policy/apex-pdp", propOrder =
68     { "key", "schemas" })
69
70 public class AxContextSchemas extends AxConcept implements AxConceptGetter<AxContextSchema> {
71     private static final long serialVersionUID = -3203734282886453582L;
72
73     @EmbeddedId
74     @XmlElement(name = "key", required = true)
75     private AxArtifactKey key;
76
77     // @formatter:off
78     @ManyToMany(cascade = CascadeType.ALL)
79     @JoinTable(
80             joinColumns = {@JoinColumn(name = "contextSchemasName", referencedColumnName = "name"),
81                     @JoinColumn(name = "contextSchemasVersion", referencedColumnName = "version")},
82             inverseJoinColumns = {@JoinColumn(name = "contextSchemaName", referencedColumnName = "name"),
83                     @JoinColumn(name = "contextSchemaVersion", referencedColumnName = "version")})
84     @XmlElement(name = "schemas", required = true)
85     private Map<AxArtifactKey, AxContextSchema> schemas;
86     // @formatter:on
87
88     /**
89      * The Default Constructor creates a {@link AxContextSchemas} object with a null artifact key and creates an empty
90      * context schemas map.
91      */
92     public AxContextSchemas() {
93         this(new AxArtifactKey());
94     }
95
96     /**
97      * Copy constructor.
98      *
99      * @param copyConcept the concept to copy from
100      */
101     public AxContextSchemas(final AxContextSchemas copyConcept) {
102         super(copyConcept);
103     }
104
105     /**
106      * The Key Constructor creates a {@link AxContextSchemas} object with the given artifact key and creates an empty
107      * context schemas map.
108      *
109      * @param key the key of the context album container
110      */
111     public AxContextSchemas(final AxArtifactKey key) {
112         this(key, new TreeMap<AxArtifactKey, AxContextSchema>());
113     }
114
115     /**
116      * This Constructor creates a {@link AxContextSchemas} object with all its fields defined.
117      *
118      * @param key the key of the context schema container
119      * @param schemas a map of the schemas to insert in the context schema container
120      */
121     public AxContextSchemas(final AxArtifactKey key, final Map<AxArtifactKey, AxContextSchema> schemas) {
122         super();
123         Assertions.argumentNotNull(key, "key may not be null");
124         Assertions.argumentNotNull(schemas, "schemas may not be null");
125
126         this.key = key;
127         this.schemas = new TreeMap<>();
128         this.schemas.putAll(schemas);
129     }
130
131     /**
132      * When a model is unmarshalled from disk or from the database, the context schema map is returned as a raw hash
133      * map. This method is called by JAXB after unmarshaling and is used to convert the hash map to a
134      * {@link NavigableMap} so that it will work with the {@link AxConceptGetter} interface.
135      *
136      * @param unmarshaller the unmarshaler that is unmarshaling the model
137      * @param parent the parent object of this object in the unmarshaler
138      */
139     public void afterUnmarshal(final Unmarshaller unmarshaller, final Object parent) {
140         // The map must be navigable to allow name and version searching, unmarshaling returns a
141         // hash map
142         final NavigableMap<AxArtifactKey, AxContextSchema> navigableContextSchemas = new TreeMap<>();
143         navigableContextSchemas.putAll(schemas);
144         schemas = navigableContextSchemas;
145     }
146
147     /*
148      * (non-Javadoc)
149      *
150      * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
151      */
152     @Override
153     public AxArtifactKey getKey() {
154         return key;
155     }
156
157     /*
158      * (non-Javadoc)
159      *
160      * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
161      */
162     @Override
163     public List<AxKey> getKeys() {
164         final List<AxKey> keyList = key.getKeys();
165         keyList.addAll(schemas.keySet());
166
167         return keyList;
168     }
169
170     /**
171      * Sets the key of the context schema container.
172      *
173      * @param key the key of the container
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 schemas in this container.
182      *
183      * @return the map of schemas
184      */
185     public Map<AxArtifactKey, AxContextSchema> getSchemasMap() {
186         return schemas;
187     }
188
189     /**
190      * Sets the map of context schemas in this container.
191      *
192      * @param schemasMap the map of schemas
193      */
194     public void setSchemasMap(final Map<AxArtifactKey, AxContextSchema> schemasMap) {
195         Assertions.argumentNotNull(schemasMap, "schemasMap may not be null");
196
197         this.schemas = new TreeMap<>();
198         this.schemas.putAll(schemasMap);
199     }
200
201     /*
202      * (non-Javadoc)
203      *
204      * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
205      * basicmodel.concepts.AxValidationResult)
206      */
207     @Override
208     public AxValidationResult validate(final AxValidationResult resultIn) {
209         AxValidationResult result = resultIn;
210
211         if (key.equals(AxArtifactKey.getNullKey())) {
212             result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
213                             "key is a null key"));
214         }
215
216         result = key.validate(result);
217
218         if (schemas.size() == 0) {
219             result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
220                             "contextSchemas may not be empty"));
221         } else {
222             for (final Entry<AxArtifactKey, AxContextSchema> contextSchemaEntry : schemas.entrySet()) {
223                 if (contextSchemaEntry.getKey().equals(AxArtifactKey.getNullKey())) {
224                     result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
225                                     "key on schemas entry " + contextSchemaEntry.getKey()
226                                                     + " may not be the null key"));
227                 } else if (contextSchemaEntry.getValue() == null) {
228                     result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
229                                     "value on schemas entry " + contextSchemaEntry.getKey() + " may not be null"));
230                 } else {
231                     if (!contextSchemaEntry.getKey().equals(contextSchemaEntry.getValue().getKey())) {
232                         result.addValidationMessage(
233                                         new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
234                                                         "key on schemas entry " + contextSchemaEntry.getKey()
235                                                                         + " does not equal entry key "
236                                                                         + contextSchemaEntry.getValue().getKey()));
237                     }
238
239                     result = contextSchemaEntry.getValue().validate(result);
240                 }
241             }
242         }
243
244         return result;
245     }
246
247     /*
248      * (non-Javadoc)
249      *
250      * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
251      */
252     @Override
253     public void clean() {
254         key.clean();
255         for (final Entry<AxArtifactKey, AxContextSchema> contextSchemaEntry : schemas.entrySet()) {
256             contextSchemaEntry.getKey().clean();
257             contextSchemaEntry.getValue().clean();
258         }
259     }
260
261     /*
262      * (non-Javadoc)
263      *
264      * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
265      */
266     @Override
267     public String toString() {
268         final StringBuilder builder = new StringBuilder();
269         builder.append(this.getClass().getSimpleName());
270         builder.append(":(");
271         builder.append("key=");
272         builder.append(key);
273         builder.append(",schemas=");
274         builder.append(schemas);
275         builder.append(")");
276         return builder.toString();
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, AxContextSchemas.class);
291
292         final AxContextSchemas copy = ((AxContextSchemas) copyObject);
293         copy.setKey(new AxArtifactKey(key));
294
295         final Map<AxArtifactKey, AxContextSchema> newcontextSchemas = new TreeMap<>();
296         for (final Entry<AxArtifactKey, AxContextSchema> contextSchemasEntry : schemas.entrySet()) {
297             newcontextSchemas.put(new AxArtifactKey(contextSchemasEntry.getKey()),
298                             new AxContextSchema(contextSchemasEntry.getValue()));
299         }
300         copy.setSchemasMap(newcontextSchemas);
301
302         return copy;
303     }
304
305     /*
306      * (non-Javadoc)
307      *
308      * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
309      */
310     @Override
311     public int hashCode() {
312         final int prime = 31;
313         int result = 1;
314         result = prime * result + key.hashCode();
315         result = prime * result + schemas.hashCode();
316         return result;
317     }
318
319     /*
320      * (non-Javadoc)
321      *
322      * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
323      */
324     @Override
325     public boolean equals(final Object obj) {
326         if (obj == null) {
327             return false;
328         }
329         if (this == obj) {
330             return true;
331         }
332         if (getClass() != obj.getClass()) {
333             return false;
334         }
335
336         final AxContextSchemas other = (AxContextSchemas) obj;
337         if (!key.equals(other.key)) {
338             return false;
339         }
340         return schemas.equals(other.schemas);
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 AxContextSchemas other = (AxContextSchemas) otherObj;
361         if (!key.equals(other.key)) {
362             return key.compareTo(other.key);
363         }
364         if (!schemas.equals(other.schemas)) {
365             return (schemas.hashCode() - other.schemas.hashCode());
366         }
367
368         return 0;
369     }
370
371     /*
372      * (non-Javadoc)
373      *
374      * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#get(org.onap.policy.apex.core.
375      * basicmodel.concepts.AxArtifactKey)
376      */
377     @Override
378     public AxContextSchema get(final AxArtifactKey conceptKey) {
379         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKey);
380     }
381
382     /*
383      * (non-Javadoc)
384      *
385      * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#get(java.lang.String)
386      */
387     @Override
388     public AxContextSchema get(final String conceptKeyName) {
389         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKeyName);
390     }
391
392     /*
393      * (non-Javadoc)
394      *
395      * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#get(java.lang.String, java.lang.String)
396      */
397     @Override
398     public AxContextSchema get(final String conceptKeyName, final String conceptKeyVersion) {
399         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKeyName,
400                         conceptKeyVersion);
401     }
402
403     /*
404      * (non-Javadoc)
405      *
406      * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#getAll(java.lang.String)
407      */
408     @Override
409     public Set<AxContextSchema> getAll(final String conceptKeyName) {
410         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).getAll(conceptKeyName);
411     }
412
413     /*
414      * (non-Javadoc)
415      *
416      * @see org.onap.policy.apex.core.basicmodel.concepts.AxConceptGetter#getAll(java.lang.String, java.lang.String)
417      */
418     @Override
419     public Set<AxContextSchema> getAll(final String conceptKeyName, final String conceptKeyVersion) {
420         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).getAll(conceptKeyName,
421                         conceptKeyVersion);
422     }
423 }