a5b56f244c2e0e762bd5fe146ede5fc5ff4956f0
[policy/apex-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019-2022 Nordix Foundation.
5  *  Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * SPDX-License-Identifier: Apache-2.0
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.apex.model.contextmodel.concepts;
24
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.NavigableMap;
29 import java.util.Set;
30 import java.util.TreeMap;
31 import javax.xml.bind.Unmarshaller;
32 import javax.xml.bind.annotation.XmlAccessType;
33 import javax.xml.bind.annotation.XmlAccessorType;
34 import javax.xml.bind.annotation.XmlElement;
35 import javax.xml.bind.annotation.XmlType;
36 import lombok.AccessLevel;
37 import lombok.EqualsAndHashCode;
38 import lombok.Getter;
39 import lombok.ToString;
40 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
41 import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
42 import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetter;
43 import org.onap.policy.apex.model.basicmodel.concepts.AxConceptGetterImpl;
44 import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
45 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
46 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
47 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
48 import org.onap.policy.common.utils.validation.Assertions;
49
50 /**
51  * This class is a context schema container and holds a map of the context schemas for an entire Apex model. All Apex
52  * models that use context schemas must have an {@link AxContextSchemas} field. The {@link AxContextSchemas} class
53  * implements the helper methods of the {@link AxConceptGetter} interface to allow {@link AxContextSchema} instances to
54  * be retrieved by calling methods directly on this class without referencing the contained map.
55  *
56  * <p>Validation checks that the container key is not null. An error is issued if no context schemas are defined in the
57  * container. Each context schema entry is checked to ensure that its key and value are not null and that the key
58  * matches the key in the map value. Each context schema entry is then validated individually.
59  */
60 @Getter
61 @ToString
62 @EqualsAndHashCode(callSuper = false)
63
64 @XmlAccessorType(XmlAccessType.FIELD)
65 @XmlType(name = "AxContextSchemas", namespace = "http://www.onap.org/policy/apex-pdp", propOrder =
66     { "key", "schemas" })
67
68 public class AxContextSchemas extends AxConcept implements AxConceptGetter<AxContextSchema> {
69     private static final long serialVersionUID = -3203734282886453582L;
70
71     @XmlElement(name = "key", required = true)
72     private AxArtifactKey key;
73
74     @XmlElement(name = "schemas", required = true)
75     @Getter(AccessLevel.NONE)
76     private Map<AxArtifactKey, AxContextSchema> schemas;
77
78     /**
79      * The Default Constructor creates a {@link AxContextSchemas} object with a null artifact key and creates an empty
80      * context schemas map.
81      */
82     public AxContextSchemas() {
83         this(new AxArtifactKey());
84     }
85
86     /**
87      * Copy constructor.
88      *
89      * @param copyConcept the concept to copy from
90      */
91     public AxContextSchemas(final AxContextSchemas copyConcept) {
92         super(copyConcept);
93     }
94
95     /**
96      * The Key Constructor creates a {@link AxContextSchemas} object with the given artifact key and creates an empty
97      * context schemas map.
98      *
99      * @param key the key of the context album container
100      */
101     public AxContextSchemas(final AxArtifactKey key) {
102         this(key, new TreeMap<>());
103     }
104
105     /**
106      * This Constructor creates a {@link AxContextSchemas} object with all its fields defined.
107      *
108      * @param key the key of the context schema container
109      * @param schemas a map of the schemas to insert in the context schema container
110      */
111     public AxContextSchemas(final AxArtifactKey key, final Map<AxArtifactKey, AxContextSchema> schemas) {
112         super();
113         Assertions.argumentNotNull(key, "key may not be null");
114         Assertions.argumentNotNull(schemas, "schemas may not be null");
115
116         this.key = key;
117         this.schemas = new TreeMap<>();
118         this.schemas.putAll(schemas);
119     }
120
121     /**
122      * When a model is unmarshalled from disk or from the database, the context schema map is returned as a raw hash
123      * map. This method is called by JAXB after unmarshaling and is used to convert the hash map to a
124      * {@link NavigableMap} so that it will work with the {@link AxConceptGetter} interface.
125      *
126      * @param unmarshaller the unmarshaler that is unmarshaling the model
127      * @param parent the parent object of this object in the unmarshaler
128      */
129     public void afterUnmarshal(final Unmarshaller unmarshaller, final Object parent) {
130         // The map must be navigable to allow name and version searching, unmarshaling returns a
131         // hash map
132         final NavigableMap<AxArtifactKey, AxContextSchema> navigableContextSchemas = new TreeMap<>();
133         navigableContextSchemas.putAll(schemas);
134         schemas = navigableContextSchemas;
135     }
136
137     /**
138      * {@inheritDoc}.
139      */
140     @Override
141     public List<AxKey> getKeys() {
142         final List<AxKey> keyList = key.getKeys();
143         keyList.addAll(schemas.keySet());
144
145         return keyList;
146     }
147
148     /**
149      * Sets the key of the context schema container.
150      *
151      * @param key the key of the container
152      */
153     public void setKey(final AxArtifactKey key) {
154         Assertions.argumentNotNull(key, "key may not be null");
155         this.key = key;
156     }
157
158     /**
159      * Gets the map of context schemas in this container.
160      *
161      * @return the map of schemas
162      */
163     public Map<AxArtifactKey, AxContextSchema> getSchemasMap() {
164         return schemas;
165     }
166
167     /**
168      * Sets the map of context schemas in this container.
169      *
170      * @param schemasMap the map of schemas
171      */
172     public void setSchemasMap(final Map<AxArtifactKey, AxContextSchema> schemasMap) {
173         Assertions.argumentNotNull(schemasMap, "schemasMap may not be null");
174
175         this.schemas = new TreeMap<>();
176         this.schemas.putAll(schemasMap);
177     }
178
179     /**
180      * {@inheritDoc}.
181      */
182     @Override
183     public AxValidationResult validate(final AxValidationResult resultIn) {
184         AxValidationResult result = resultIn;
185
186         if (key.equals(AxArtifactKey.getNullKey())) {
187             result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
188                             "key is a null key"));
189         }
190
191         result = key.validate(result);
192
193         if (schemas.size() == 0) {
194             result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
195                             "contextSchemas may not be empty"));
196         } else {
197             for (final Entry<AxArtifactKey, AxContextSchema> contextSchemaEntry : schemas.entrySet()) {
198                 if (contextSchemaEntry.getKey().equals(AxArtifactKey.getNullKey())) {
199                     result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
200                                     "key on schemas entry " + contextSchemaEntry.getKey()
201                                                     + " may not be the null key"));
202                 } else if (contextSchemaEntry.getValue() == null) {
203                     result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
204                                     "value on schemas entry " + contextSchemaEntry.getKey() + " may not be null"));
205                 } else {
206                     if (!contextSchemaEntry.getKey().equals(contextSchemaEntry.getValue().getKey())) {
207                         result.addValidationMessage(
208                                         new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
209                                                         "key on schemas entry " + contextSchemaEntry.getKey()
210                                                                         + " does not equal entry key "
211                                                                         + contextSchemaEntry.getValue().getKey()));
212                     }
213
214                     result = contextSchemaEntry.getValue().validate(result);
215                 }
216             }
217         }
218
219         return result;
220     }
221
222     /**
223      * {@inheritDoc}.
224      */
225     @Override
226     public void clean() {
227         key.clean();
228         for (final Entry<AxArtifactKey, AxContextSchema> contextSchemaEntry : schemas.entrySet()) {
229             contextSchemaEntry.getKey().clean();
230             contextSchemaEntry.getValue().clean();
231         }
232     }
233
234     /**
235      * {@inheritDoc}.
236      */
237     @Override
238     public AxConcept copyTo(final AxConcept target) {
239         Assertions.argumentNotNull(target, "target may not be null");
240
241         final Object copyObject = target;
242         Assertions.instanceOf(copyObject, AxContextSchemas.class);
243
244         final AxContextSchemas copy = ((AxContextSchemas) copyObject);
245         copy.setKey(new AxArtifactKey(key));
246
247         final Map<AxArtifactKey, AxContextSchema> newcontextSchemas = new TreeMap<>();
248         for (final Entry<AxArtifactKey, AxContextSchema> contextSchemasEntry : schemas.entrySet()) {
249             newcontextSchemas.put(new AxArtifactKey(contextSchemasEntry.getKey()),
250                             new AxContextSchema(contextSchemasEntry.getValue()));
251         }
252         copy.setSchemasMap(newcontextSchemas);
253
254         return copy;
255     }
256
257     /**
258      * {@inheritDoc}.
259      */
260     @Override
261     public int compareTo(final AxConcept otherObj) {
262         if (otherObj == null) {
263             return -1;
264         }
265         if (this == otherObj) {
266             return 0;
267         }
268         if (getClass() != otherObj.getClass()) {
269             return this.hashCode() - otherObj.hashCode();
270         }
271
272         final AxContextSchemas other = (AxContextSchemas) otherObj;
273         if (!key.equals(other.key)) {
274             return key.compareTo(other.key);
275         }
276         if (!schemas.equals(other.schemas)) {
277             return (schemas.hashCode() - other.schemas.hashCode());
278         }
279
280         return 0;
281     }
282
283     /**
284      * {@inheritDoc}.
285      */
286     @Override
287     public AxContextSchema get(final AxArtifactKey conceptKey) {
288         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKey);
289     }
290
291     /**
292      * {@inheritDoc}.
293      */
294     @Override
295     public AxContextSchema get(final String conceptKeyName) {
296         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKeyName);
297     }
298
299     /**
300      * {@inheritDoc}.
301      */
302     @Override
303     public AxContextSchema get(final String conceptKeyName, final String conceptKeyVersion) {
304         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKeyName,
305                         conceptKeyVersion);
306     }
307
308     /**
309      * {@inheritDoc}.
310      */
311     @Override
312     public Set<AxContextSchema> getAll(final String conceptKeyName) {
313         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).getAll(conceptKeyName);
314     }
315
316     /**
317      * {@inheritDoc}.
318      */
319     @Override
320     public Set<AxContextSchema> getAll(final String conceptKeyName, final String conceptKeyVersion) {
321         return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).getAll(conceptKeyName,
322                         conceptKeyVersion);
323     }
324 }