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.contextmodel.concepts;
23 import java.util.List;
25 import javax.persistence.Column;
26 import javax.persistence.Convert;
27 import javax.persistence.EmbeddedId;
28 import javax.persistence.Entity;
29 import javax.persistence.Table;
30 import javax.xml.bind.annotation.XmlAccessType;
31 import javax.xml.bind.annotation.XmlAccessorType;
32 import javax.xml.bind.annotation.XmlElement;
33 import javax.xml.bind.annotation.XmlRootElement;
34 import javax.xml.bind.annotation.XmlType;
35 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
37 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
38 import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
39 import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
40 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
41 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
42 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
43 import org.onap.policy.apex.model.basicmodel.dao.converters.CDataConditioner;
44 import org.onap.policy.apex.model.utilities.Assertions;
47 * This class holds a data schema definition in Apex. A data schema describes the structure of a single atom of data
48 * handled by Apex. This atom of data can be a primitive type such as an integer or a string, or it can be a more
49 * complex data type such as a Java object or an object described using a data definition language such as Avro. The
50 * schema flavour defines the type of schema being defined and the schema itself defines the schema. The schema flavour
51 * is used by Apex to look up and load a plugin class that understands and interprets the schema definition and can
52 * create instances of classes for the schema.
54 * An {@link AxContextSchema} is used to define each parameter in Apex events, the messages that enter, exit, and are
55 * passed internally in Apex. In addition, an Apex {@link AxContextAlbum} instances hold a map of
56 * {@link AxContextSchema} instances to represent the context being managed as an {@link AxContextAlbum}. For example,
57 * the state of all cells in a mobile network might be represented as an {@link AxContextAlbum} with its
58 * {@link AxContextSchema} being defined as @code cell} objects.
60 * Validation checks that the schema key is not null. It also checks that the schema flavour is defined and matches the
61 * regular expression {@link SCHEMA_FLAVOUR_REGEXP}. Finally, validation checks that the defined schema is not a blank
65 @Table(name = "AxContextSchema")
67 @XmlAccessorType(XmlAccessType.FIELD)
68 @XmlRootElement(name = "apexContextSchema", namespace = "http://www.onap.org/policy/apex-pdp")
69 @XmlType(name = "AxContextSchema", namespace = "http://www.onap.org/policy/apex-pdp",
70 propOrder = { "key", "schemaFlavour", "schemaDefinition" })
72 public class AxContextSchema extends AxConcept {
73 private static final String SCHEMA_FLAVOUR = "schemaFlavour";
74 private static final String WHITESPACE_REGEXP = "\\s+$";
76 private static final long serialVersionUID = -6443016863162692288L;
78 /** Regular expression that constrains what values a schema flavour can have. */
79 public static final String SCHEMA_FLAVOUR_REGEXP = "[A-Za-z0-9\\-_]+";
81 /** An undefined schema flavour has this value. */
82 public static final String SCHEMA_FLAVOUR_UNDEFINED = "UNDEFINED";
84 /** The maximum permissible size of a schema definition. */
85 public static final int MAX_SCHEMA_SIZE = 32672; // The maximum size supported by Apache Derby
88 @XmlElement(name = "key", required = true)
89 private AxArtifactKey key;
91 @Column(name = SCHEMA_FLAVOUR)
92 @XmlElement(required = true)
93 private String schemaFlavour;
95 @Column(name = "schemaDefinition", length = MAX_SCHEMA_SIZE)
96 @Convert(converter = CDataConditioner.class)
97 @XmlJavaTypeAdapter(value = CDataConditioner.class)
98 @XmlElement(name = "schemaDefinition", required = true)
99 private String schemaDefinition;
102 * The default constructor creates a context schema with a null artifact key. The flavour of the context album is
103 * set as {@link SCHEMA_FLAVOUR_UNDEFINED} and the schema itself is defined as an empty string.
105 public AxContextSchema() {
106 this(new AxArtifactKey());
107 schemaFlavour = SCHEMA_FLAVOUR_UNDEFINED;
113 * @param copyConcept the concept to copy from
115 public AxContextSchema(final AxContextSchema copyConcept) {
120 * The key constructor creates a context schema with the given artifact key. The flavour of the context album is set
121 * as {@link SCHEMA_FLAVOUR_UNDEFINED} and the schema itself is defined as an empty string.
125 public AxContextSchema(final AxArtifactKey key) {
126 this(key, SCHEMA_FLAVOUR_UNDEFINED, "");
130 * This Constructor creates a context schema with all of its fields defined.
133 * @param schemaFlavour the schema flavour
134 * @param schemaDefinition the schema definition
136 public AxContextSchema(final AxArtifactKey key, final String schemaFlavour, final String schemaDefinition) {
138 Assertions.argumentNotNull(key, "key may not be null");
139 Assertions.argumentNotNull(schemaFlavour, "schemaFlavour may not be null");
140 Assertions.argumentNotNull(schemaDefinition, "schemaDefinition may not be null");
143 this.schemaFlavour = Assertions.validateStringParameter(SCHEMA_FLAVOUR, schemaFlavour, SCHEMA_FLAVOUR_REGEXP);
144 this.schemaDefinition = schemaDefinition.replaceAll(WHITESPACE_REGEXP, "");
150 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKey()
153 public AxArtifactKey getKey() {
160 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#getKeys()
163 public List<AxKey> getKeys() {
164 return key.getKeys();
168 * Sets the key of the context schema.
170 * @param key the key of the context schema
172 public void setKey(final AxArtifactKey key) {
173 Assertions.argumentNotNull(key, "key may not be null");
178 * Gets the schema flavour, which defines the schema definition type being used.
180 * @return the schema flavour
182 public String getSchemaFlavour() {
183 return schemaFlavour;
187 * Sets the schema flavour, which defines the type of schema definition being used.
189 * @param schemaFlavour the schema flavour
191 public void setSchemaFlavour(final String schemaFlavour) {
192 this.schemaFlavour = Assertions.validateStringParameter(SCHEMA_FLAVOUR, schemaFlavour, SCHEMA_FLAVOUR_REGEXP);
196 * Gets the schema, which defines the structure of this data schema atom.
198 * @return the schema definition
200 public String getSchema() {
201 return schemaDefinition;
205 * Sets the schema, which defines the structure of this data schema atom.
207 * @param schema the schema definition
209 public void setSchema(final String schema) {
210 Assertions.argumentNotNull(schema, "schema may not be null");
211 this.schemaDefinition = schema.replaceAll(WHITESPACE_REGEXP, "");
217 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#validate(org.onap.policy.apex.model.
218 * basicmodel.concepts.AxValidationResult)
221 public AxValidationResult validate(final AxValidationResult resultIn) {
222 AxValidationResult result = resultIn;
224 if (key.equals(AxArtifactKey.getNullKey())) {
225 result.addValidationMessage(
226 new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
229 result = key.validate(result);
231 if (schemaFlavour.replaceAll(WHITESPACE_REGEXP, "").length() == 0
232 || schemaFlavour.equals(SCHEMA_FLAVOUR_UNDEFINED)) {
233 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
234 "schema flavour is not defined"));
238 Assertions.validateStringParameter(SCHEMA_FLAVOUR, schemaFlavour, SCHEMA_FLAVOUR_REGEXP);
239 } catch (final IllegalArgumentException e) {
240 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
241 "schema flavour invalid-" + e.getMessage()));
244 if (schemaDefinition.replaceAll(WHITESPACE_REGEXP, "").length() == 0) {
245 result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
246 "no schemaDefinition specified, schemaDefinition may not be blank"));
255 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#clean()
258 public void clean() {
260 schemaFlavour = Assertions.validateStringParameter(SCHEMA_FLAVOUR, schemaFlavour, SCHEMA_FLAVOUR_REGEXP);
261 schemaDefinition = schemaDefinition.replaceAll(WHITESPACE_REGEXP, "");
267 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#toString()
270 public String toString() {
271 final StringBuilder builder = new StringBuilder();
272 builder.append(this.getClass().getSimpleName());
273 builder.append(":(");
274 builder.append("key=");
276 builder.append(",schemaFlavour=");
277 builder.append(schemaFlavour);
278 builder.append(",schemaDefinition=");
279 builder.append(schemaDefinition);
281 return builder.toString();
287 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#copyTo(org.onap.policy.apex.model.
288 * basicmodel.concepts.AxConcept)
291 public AxConcept copyTo(final AxConcept target) {
292 Assertions.argumentNotNull(target, "target may not be null");
294 final Object copyObject = target;
295 Assertions.instanceOf(copyObject, AxContextSchema.class);
297 final AxContextSchema copy = ((AxContextSchema) copyObject);
298 copy.setKey(new AxArtifactKey(key));
299 copy.setSchemaFlavour(schemaFlavour);
300 copy.setSchema(schemaDefinition);
308 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#hashCode()
311 public int hashCode() {
312 final int prime = 31;
314 result = prime * result + key.hashCode();
315 result = prime * result + schemaFlavour.hashCode();
316 result = prime * result + schemaDefinition.hashCode();
323 * @see org.onap.policy.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
326 public boolean equals(final Object obj) {
334 if (getClass() != obj.getClass()) {
338 final AxContextSchema other = (AxContextSchema) obj;
340 if (!key.equals(other.key)) {
343 if (!schemaFlavour.equals(other.schemaFlavour)) {
346 final String thisSchema = CDataConditioner.clean(schemaDefinition).replaceAll("\n", "");
347 final String otherSchema = CDataConditioner.clean(other.schemaDefinition).replaceAll("\n", "");
348 return thisSchema.equals(otherSchema);
354 * @see java.lang.Comparable#compareTo(java.lang.Object)
357 public int compareTo(final AxConcept otherObj) {
358 if (otherObj == null) {
361 if (this == otherObj) {
364 if (getClass() != otherObj.getClass()) {
365 return this.hashCode() - otherObj.hashCode();
368 final AxContextSchema other = (AxContextSchema) otherObj;
369 if (!key.equals(other.key)) {
370 return key.compareTo(other.key);
372 if (!schemaFlavour.equals(other.schemaFlavour)) {
373 return schemaFlavour.compareTo(other.schemaFlavour);
375 final String thisSchema = CDataConditioner.clean(schemaDefinition).replaceAll("\n", "");
376 final String otherSchema = CDataConditioner.clean(other.schemaDefinition).replaceAll("\n", "");
377 return thisSchema.compareTo(otherSchema);