aboutsummaryrefslogtreecommitdiffstats
path: root/model/context-model/src/main/java/org/onap
diff options
context:
space:
mode:
authorwaqas.ikram <waqas.ikram@ericsson.com>2018-05-24 17:00:47 +0100
committerwaqas.ikram <waqas.ikram@ericsson.com>2018-05-24 17:30:18 +0100
commit5abd3063949496c231ed8d3013c2ab17fc9288bb (patch)
tree5354cda64e12195835ab0ac511f3334fcb0a759c /model/context-model/src/main/java/org/onap
parentf524b88f7675065c7d33bb019257e165de33230b (diff)
Adding apex context-model module
Change-Id: Ia80b2caa0f76ecd7a80ece79e5cf88ac9de048ac Issue-ID: POLICY-856 Signed-off-by: waqas.ikram <waqas.ikram@ericsson.com>
Diffstat (limited to 'model/context-model/src/main/java/org/onap')
-rw-r--r--model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextAlbum.java426
-rw-r--r--model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextAlbums.java427
-rw-r--r--model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextModel.java346
-rw-r--r--model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextSchema.java383
-rw-r--r--model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextSchemas.java424
-rw-r--r--model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/package-info.java27
-rw-r--r--model/context-model/src/main/java/org/onap/apex/model/contextmodel/handling/ContextComparer.java70
-rw-r--r--model/context-model/src/main/java/org/onap/apex/model/contextmodel/handling/package-info.java27
8 files changed, 2130 insertions, 0 deletions
diff --git a/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextAlbum.java b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextAlbum.java
new file mode 100644
index 000000000..045ea0aba
--- /dev/null
+++ b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextAlbum.java
@@ -0,0 +1,426 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.apex.model.contextmodel.concepts;
+
+import java.util.List;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.apex.model.basicmodel.concepts.AxKey;
+import org.onap.apex.model.basicmodel.concepts.AxKeyUse;
+import org.onap.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class is used to define an album of context.
+ * <p>
+ * A context album is a distributed map of context that will be distributed across all process
+ * instances that require access to it. This class defines the schema (structure) of the items in
+ * the context album, whether the items on the context album are writable or not, and what the scope
+ * of the context album is.
+ * <p>
+ * The structure of items (objects) the context album is defined as a schema, which is understood by
+ * whatever schema implementation is being used for the context album.
+ * <p>
+ * The scope of a context album is a string field, understood by whatever distribution mechanism is
+ * being used for the context album. The distribution mechanism uses the scope of the context album
+ * to decide to which executable entities a given context album is distributed.
+ * <p>
+ * The writable flag on a context album defines whether users of a context album can write to the
+ * context album or just read objects from the context album.
+ * <p>
+ * Validation checks that the album key and the context schema key are not null and that the scope
+ * field is not undefined and matches the regular expression {@link SCOPE_REGEXP}.
+ */
+@Entity
+@Table(name = "AxContextAlbum")
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "apexContextAlbum", namespace = "http://www.ericsson.com/apex")
+@XmlType(name = "AxContextAlbum", namespace = "http://www.ericsson.com/apex",
+ propOrder = {"key", "scope", "isWritable", "itemSchema"})
+
+public class AxContextAlbum extends AxConcept {
+ private static final String SCOPE_STRING = "scope";
+
+ private static final long serialVersionUID = 4290442590545820316L;
+
+ /**
+ * The legal values for the scope of a context album is constrained by this regular expression.
+ */
+ public static final String SCOPE_REGEXP = "[A-Za-z0-9\\-_]+";
+
+ /** The value of scope for a context album for which a scope has not been specified. */
+ public static final String SCOPE_UNDEFINED = "UNDEFINED";
+
+ private static final int HASH_PRIME_0 = 1231;
+ private static final int HASH_PRIME_1 = 1237;
+
+ @EmbeddedId
+ @XmlElement(name = "key", required = true)
+ private AxArtifactKey key;
+
+ @Column(name = SCOPE_STRING)
+ @XmlElement(name = SCOPE_STRING, required = true)
+ private String scope;
+
+ @Column(name = "isWritable")
+ @XmlElement(name = "isWritable", required = true)
+ private boolean isWritable;
+
+ // @formatter:off
+ @Embedded
+ @AttributeOverrides({
+ @AttributeOverride(name = "name", column = @Column(name = "itemSchemaName")),
+ @AttributeOverride(name = "version", column = @Column(name = "itemSchemaVersion"))
+ })
+ @Column(name = "itemSchema")
+ @XmlElement(name = "itemSchema", required = true)
+ private AxArtifactKey itemSchema;
+ // @formatter:on
+
+ /**
+ * The default constructor creates a context album with a null artifact key. The scope of the
+ * context album is set as {@link SCOPE_UNDEFINED}, the album is writable, and the artifact key
+ * of the context schema is set to the null artifact key.
+ */
+ public AxContextAlbum() {
+ this(new AxArtifactKey());
+ scope = SCOPE_UNDEFINED;
+ isWritable = true;
+ itemSchema = AxArtifactKey.getNullKey();
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxContextAlbum(final AxContextAlbum copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The keyed constructor creates a context album with the specified artifact key. The scope of
+ * the context album is set as {@link SCOPE_UNDEFINED}, the album is writable, and the artifact
+ * key of the context schema is set to the null artifact key.
+ *
+ * @param key the key of the context album
+ */
+ public AxContextAlbum(final AxArtifactKey key) {
+ this(key, SCOPE_UNDEFINED, true, AxArtifactKey.getNullKey());
+ }
+
+ /**
+ * Constructor that sets all the fields of the context album.
+ *
+ * @param key the key of the context album
+ * @param scope the scope field, must match the regular expression {@link SCOPE_REGEXP}
+ * @param isWritable specifies whether the context album will be writable or not
+ * @param itemSchema the artifact key of the context schema to use for this context album
+ */
+ public AxContextAlbum(final AxArtifactKey key, final String scope, final boolean isWritable,
+ final AxArtifactKey itemSchema) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(scope, "scope may not be null");
+ Assertions.argumentNotNull(itemSchema, "itemSchema may not be null");
+
+ this.key = key;
+ this.scope = Assertions.validateStringParameter(SCOPE_STRING, scope, SCOPE_REGEXP);
+ this.isWritable = isWritable;
+ this.itemSchema = itemSchema;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ keyList.add(new AxKeyUse(itemSchema.getKey()));
+
+ return keyList;
+ }
+
+ /**
+ * Sets the key of the context album.
+ *
+ * @param key the context album key
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the scope of the context album.
+ *
+ * @return the context album scope
+ */
+ public String getScope() {
+ return scope;
+ }
+
+ /**
+ * Sets the scope of the context album.
+ *
+ * @param scope the context album scope
+ */
+ public void setScope(final String scope) {
+ Assertions.argumentNotNull(scope, "scope may not be null");
+ this.scope = Assertions.validateStringParameter(SCOPE_STRING, scope, SCOPE_REGEXP);
+ }
+
+ /**
+ * Sets whether the album is writable or not.
+ *
+ * @param writable the writable flag value
+ */
+ public void setWritable(final boolean writable) {
+ this.isWritable = writable;
+ }
+
+ /**
+ * Checks if the album is writable.
+ *
+ * @return true, if the album is writable
+ */
+ public boolean isWritable() {
+ return isWritable;
+ }
+
+ /**
+ * Gets the artifact key of the item schema of this context album.
+ *
+ * @return the item schema key
+ */
+ public AxArtifactKey getItemSchema() {
+ return itemSchema;
+ }
+
+ /**
+ * Sets the artifact key of the item schema of this context album.
+ *
+ * @param itemSchema the item schema key
+ */
+ public void setItemSchema(final AxArtifactKey itemSchema) {
+ Assertions.argumentNotNull(itemSchema, "itemSchema key may not be null");
+ this.itemSchema = itemSchema;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#validate(com.ericsson.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+ result = key.validate(result);
+
+ if (scope.replaceAll("\\s+$", "").length() == 0 || scope.equals(SCOPE_UNDEFINED)) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "scope is not defined"));
+ }
+
+ try {
+ Assertions.validateStringParameter(SCOPE_STRING, scope, SCOPE_REGEXP);
+ } catch (final IllegalArgumentException e) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "scope invalid-" + e.getMessage()));
+ }
+
+ if (itemSchema.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "itemSchema reference is a null key, an item schema must be specified"));
+ }
+ result = itemSchema.validate(result);
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ scope = Assertions.validateStringParameter(SCOPE_STRING, scope, SCOPE_REGEXP);
+ itemSchema.clean();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",scope=");
+ builder.append(scope);
+ builder.append(",isWritable=");
+ builder.append(isWritable);
+ builder.append(",itemSchema=");
+ builder.append(itemSchema);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#copyTo(com.ericsson.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "targetObject may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxContextAlbum.class);
+
+ final AxContextAlbum copy = ((AxContextAlbum) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+ copy.setScope(scope);
+ copy.setWritable(isWritable);
+ copy.setItemSchema(new AxArtifactKey(itemSchema));
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + scope.hashCode();
+ result = prime * result + (isWritable ? HASH_PRIME_0 : HASH_PRIME_1);
+ result = prime * result + itemSchema.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxContextAlbum other = (AxContextAlbum) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!scope.equals(other.scope)) {
+ return false;
+ }
+ if (isWritable != other.isWritable) {
+ return (false);
+ }
+ return itemSchema.equals(other.itemSchema);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxContextAlbum other = (AxContextAlbum) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!scope.equals(other.scope)) {
+ return scope.compareTo(other.scope);
+ }
+ if (isWritable != other.isWritable) {
+ return (isWritable ? 1 : -1);
+ }
+ return itemSchema.compareTo(other.itemSchema);
+ }
+}
diff --git a/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextAlbums.java b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextAlbums.java
new file mode 100644
index 000000000..e48d064cb
--- /dev/null
+++ b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextAlbums.java
@@ -0,0 +1,427 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.apex.model.contextmodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javax.persistence.CascadeType;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.apex.model.basicmodel.concepts.AxConceptGetter;
+import org.onap.apex.model.basicmodel.concepts.AxConceptGetterImpl;
+import org.onap.apex.model.basicmodel.concepts.AxKey;
+import org.onap.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class is a context album container and holds a map of the context albums for an entire Apex
+ * model. All Apex models that use context albums must have an {@link AxContextAlbums} field. The
+ * {@link AxContextAlbums} class implements the helper methods of the {@link AxConceptGetter}
+ * interface to allow {@link AxContextAlbum} instances to be retrieved by calling methods directly
+ * on this class without referencing the contained map.
+ * <p>
+ * Validation checks that the container key is not null. An observation is issued if no context
+ * albums are defined in the container. If context albums do exist, they are checked to ensure that
+ * keys and values are not null and that the map key matches the key in the map value for all album
+ * entries. Each context album entry is then validated individually.
+ */
+@Entity
+@Table(name = "AxContextAlbums")
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "AxContextAlbums", namespace = "http://www.ericsson.com/apex", propOrder = {"key", "albums"})
+
+public final class AxContextAlbums extends AxConcept implements AxConceptGetter<AxContextAlbum> {
+ private static final long serialVersionUID = -4844259809024470975L;
+
+ @EmbeddedId
+ @XmlElement(name = "key", required = true)
+ private AxArtifactKey key;
+
+ // @formatter:off
+ @OneToMany(cascade = CascadeType.ALL)
+ @JoinTable(joinColumns = {@JoinColumn(name = "contextName", referencedColumnName = "name"),
+ @JoinColumn(name = "contextVersion", referencedColumnName = "version")})
+ @XmlElement(name = "albums", required = true)
+ private Map<AxArtifactKey, AxContextAlbum> albums;
+ // @formatter:on
+
+ /**
+ * The Default Constructor creates a {@link AxContextAlbums} object with a null artifact key and
+ * creates an empty context album map.
+ */
+ public AxContextAlbums() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxContextAlbums(final AxContextAlbums copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Key Constructor creates a {@link AxContextAlbums} object with the given artifact key and
+ * creates an empty context album map.
+ *
+ * @param key the key of the context album container
+ */
+ public AxContextAlbums(final AxArtifactKey key) {
+ this(key, new TreeMap<AxArtifactKey, AxContextAlbum>());
+ }
+
+ /**
+ * Constructor that creates the context album map with the given albums and key.
+ *
+ * @param key the key of the context album container
+ * @param albums the context albums to place in this context album container
+ */
+ public AxContextAlbums(final AxArtifactKey key, final Map<AxArtifactKey, AxContextAlbum> albums) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(albums, "albums may not be null");
+
+ this.key = key;
+ this.albums = new TreeMap<>();
+ this.albums.putAll(albums);
+ }
+
+ /**
+ * When a model is unmarshalled from disk or from the database, the context album map is
+ * returned as a raw hash map. This method is called by JAXB after unmarshaling and is used to
+ * convert the hash map to a {@link NavigableMap} so that it will work with the
+ * {@link AxConceptGetter} interface.
+ *
+ * @param u the unmarshaler that is unmarshaling the model
+ * @param parent the parent object of this object in the unmarshaler
+ */
+ public void afterUnmarshal(final Unmarshaller u, final Object parent) {
+ // The map must be navigable to allow name and version searching, unmarshaling returns a
+ // hash map
+ final NavigableMap<AxArtifactKey, AxContextAlbum> navigableAlbums = new TreeMap<>();
+ navigableAlbums.putAll(albums);
+ albums = navigableAlbums;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ for (final AxContextAlbum contextAlbum : albums.values()) {
+ keyList.addAll(contextAlbum.getKeys());
+ }
+
+ return keyList;
+ }
+
+ /**
+ * Sets the key of the context album container.
+ *
+ * @param key the context album container key
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the map of context albums from the context album container.
+ *
+ * @return the context album map
+ */
+ public Map<AxArtifactKey, AxContextAlbum> getAlbumsMap() {
+ return albums;
+ }
+
+ /**
+ * Sets the map of context albums from the context album container.
+ *
+ * @param albumsMap the map of context albums to place in the container
+ */
+ public void setAlbumsMap(final Map<AxArtifactKey, AxContextAlbum> albumsMap) {
+ Assertions.argumentNotNull(albumsMap, "albums may not be null");
+ this.albums = new TreeMap<>();
+ this.albums.putAll(albumsMap);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final Entry<AxArtifactKey, AxContextAlbum> contextAlbumEntry : albums.entrySet()) {
+ contextAlbumEntry.getKey().clean();
+ contextAlbumEntry.getValue().clean();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",albums=");
+ builder.append(albums);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#validate(com.ericsson.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (albums.size() == 0) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.OBSERVATION, "albums are empty"));
+ } else {
+ for (final Entry<AxArtifactKey, AxContextAlbum> contextAlbumEntry : albums.entrySet()) {
+ if (contextAlbumEntry.getKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on context album entry " + contextAlbumEntry.getKey() + " may not be the null key"));
+ } else if (contextAlbumEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on context album entry " + contextAlbumEntry.getKey() + " may not be null"));
+ } else {
+ if (!contextAlbumEntry.getKey().equals(contextAlbumEntry.getValue().getKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on context album entry key " + contextAlbumEntry.getKey()
+ + " does not equal context album value key "
+ + contextAlbumEntry.getValue().getKey()));
+ }
+
+ result = contextAlbumEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#copyTo(com.ericsson.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxContextAlbums.class);
+
+ final AxContextAlbums copy = ((AxContextAlbums) copyObject);
+ copy.setKey(key);
+ final Map<AxArtifactKey, AxContextAlbum> newContextAlbum = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxContextAlbum> contextAlbumEntry : albums.entrySet()) {
+ newContextAlbum.put(new AxArtifactKey(contextAlbumEntry.getKey()),
+ new AxContextAlbum(contextAlbumEntry.getValue()));
+ }
+ copy.setAlbumsMap(newContextAlbum);
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + albums.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxContextAlbums other = (AxContextAlbums) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return albums.equals(other.albums);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxContextAlbums other = (AxContextAlbums) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!albums.equals(other.albums)) {
+ return (albums.hashCode() - other.albums.hashCode());
+ }
+
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConceptGetter#get(com.ericsson.apex.model.
+ * basicmodel.concepts.AxArtifactKey)
+ */
+ @Override
+ public AxContextAlbum get(final AxArtifactKey conceptKey) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextAlbum>) albums).get(conceptKey);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConceptGetter#get(java.lang.String)
+ */
+ @Override
+ public AxContextAlbum get(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextAlbum>) albums).get(conceptKeyName);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConceptGetter#get(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public AxContextAlbum get(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextAlbum>) albums).get(conceptKeyName,
+ conceptKeyVersion);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConceptGetter#getAll(java.lang.String)
+ */
+ @Override
+ public Set<AxContextAlbum> getAll(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextAlbum>) albums).getAll(conceptKeyName);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConceptGetter#getAll(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public Set<AxContextAlbum> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextAlbum>) albums).getAll(conceptKeyName,
+ conceptKeyVersion);
+ }
+}
diff --git a/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextModel.java b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextModel.java
new file mode 100644
index 000000000..dcd381872
--- /dev/null
+++ b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextModel.java
@@ -0,0 +1,346 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.apex.model.contextmodel.concepts;
+
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.apex.model.basicmodel.concepts.AxKey;
+import org.onap.apex.model.basicmodel.concepts.AxKeyInformation;
+import org.onap.apex.model.basicmodel.concepts.AxModel;
+import org.onap.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * A container class for an Apex context model. This class is a container class that allows an Apex
+ * model to be constructed that just contains context and the key information for that context. The
+ * model contains schema definitions and the definitions of context albums that use those schemas.
+ * In the case where Apex context is being used without policy or independent of policy, an Apex
+ * context model is sufficient to get Apex context working.
+ * <p>
+ * Validation runs {@link AxModel} validation on the model. In addition, the
+ * {@link AxContextSchemas} and {@link AxContextAlbums} validation is run on the context schemas and
+ * albums in the model.
+ */
+@Entity
+@Table(name = "AxContextModel")
+
+@XmlRootElement(name = "apexContextModel", namespace = "http://www.ericsson.com/apex")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "AxContextModel", namespace = "http://www.ericsson.com/apex", propOrder = {"schemas", "albums"})
+
+public class AxContextModel extends AxModel {
+ private static final long serialVersionUID = 8800599637708309945L;
+
+ // @formatter:off
+ @OneToOne(cascade = CascadeType.ALL)
+ @JoinColumns({
+ @JoinColumn(name = "schemasName", referencedColumnName = "name"),
+ @JoinColumn(name = "schemasVersion", referencedColumnName = "version")
+ })
+ @XmlElement(name = "schemas", required = true)
+ private AxContextSchemas schemas;
+
+ @OneToOne(cascade = CascadeType.ALL)
+ @JoinColumns({
+ @JoinColumn(name = "albumsName", referencedColumnName = "name"),
+ @JoinColumn(name = "albumsVersion", referencedColumnName = "version")
+ })
+ @XmlElement(name = "albums", required = true)
+ private AxContextAlbums albums;
+ // @formatter:on
+
+ /**
+ * The Default Constructor creates a {@link AxContextModel} object with a null artifact key and
+ * creates an empty context model.
+ */
+ public AxContextModel() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * The Key Constructor creates a {@link AxContextModel} object with the given artifact key and
+ * creates an empty context model.
+ *
+ * @param key the key of the context model
+ */
+ public AxContextModel(final AxArtifactKey key) {
+ this(key, new AxContextSchemas(new AxArtifactKey(key.getName() + "_Schemas", key.getVersion())),
+ new AxContextAlbums(new AxArtifactKey(key.getName() + "_Albums", key.getVersion())),
+ new AxKeyInformation(new AxArtifactKey(key.getName() + "_KeyInfo", key.getVersion())));
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxContextModel(final AxContextModel copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * Constructor that initiates a {@link AxContextModel} with schemas and keys for those schemas.
+ * An empty {@link AxContextAlbums} container is created.
+ *
+ * @param key the key of the context model
+ * @param schemas the context schema definitions
+ * @param keyInformation the key information for those context schemas
+ */
+ public AxContextModel(final AxArtifactKey key, final AxContextSchemas schemas,
+ final AxKeyInformation keyInformation) {
+ this(key, schemas, new AxContextAlbums(new AxArtifactKey(key.getName() + "_Albums", key.getVersion())),
+ keyInformation);
+ }
+
+ /**
+ * Constructor that initiates a {@link AxContextModel} with all its fields.
+ *
+ * @param key the key of the context model
+ * @param schemas the context schema definitions
+ * @param albums the context album container containing context albums
+ * @param keyInformation the key information for those context schemas
+ */
+ public AxContextModel(final AxArtifactKey key, final AxContextSchemas schemas, final AxContextAlbums albums,
+ final AxKeyInformation keyInformation) {
+ super(key, keyInformation);
+ Assertions.argumentNotNull(schemas, "schemas may not be null");
+ Assertions.argumentNotNull(albums, "albums may not be null");
+ this.schemas = schemas;
+ this.albums = albums;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxModel#register()
+ */
+ @Override
+ public void register() {
+ super.register();
+ ModelService.registerModel(AxContextSchemas.class, getSchemas());
+ ModelService.registerModel(AxContextAlbums.class, getAlbums());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxModel#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = super.getKeys();
+
+ keyList.addAll(schemas.getKeys());
+ keyList.addAll(albums.getKeys());
+
+ return keyList;
+ }
+
+ /**
+ * Gets the context schemas from the model.
+ *
+ * @return the context schemas
+ */
+ public AxContextSchemas getSchemas() {
+ return schemas;
+ }
+
+ /**
+ * Sets the context schemas on the model.
+ *
+ * @param schemas the context schemas
+ */
+ public void setSchemas(final AxContextSchemas schemas) {
+ Assertions.argumentNotNull(schemas, "schemas may not be null");
+ this.schemas = schemas;
+ }
+
+ /**
+ * Gets the context albums from the model.
+ *
+ * @return the context albums
+ */
+ public AxContextAlbums getAlbums() {
+ return albums;
+ }
+
+ /**
+ * Sets the context albums on the model.
+ *
+ * @param albums the context albums
+ */
+ public void setAlbums(final AxContextAlbums albums) {
+ Assertions.argumentNotNull(albums, "albums may not be null");
+ this.albums = albums;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxModel#validate(com.ericsson.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ result = super.validate(result);
+ result = schemas.validate(result);
+ return albums.validate(result);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxModel#clean()
+ */
+ @Override
+ public void clean() {
+ super.clean();
+ schemas.clean();
+ albums.clean();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxModel#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append(super.toString());
+ builder.append(",schemas=");
+ builder.append(schemas);
+ builder.append(",albums=");
+ builder.append(albums);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#copyTo(com.ericsson.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxContextModel.class);
+
+ final AxContextModel copy = ((AxContextModel) copyObject);
+ super.copyTo(target);
+ copy.setSchemas(new AxContextSchemas(schemas));
+ copy.setAlbums(new AxContextAlbums(albums));
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxModel#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + super.hashCode();
+ result = prime * result + schemas.hashCode();
+ result = prime * result + albums.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxModel#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ throw new IllegalArgumentException("comparison object may not be null");
+ }
+
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxContextModel other = (AxContextModel) obj;
+ if (!super.equals(other)) {
+ return false;
+ }
+ if (!schemas.equals(other.schemas)) {
+ return false;
+ }
+ return albums.equals(other.albums);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxModel#compareTo(com.ericsson.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxContextModel other = (AxContextModel) otherObj;
+ if (!super.equals(other)) {
+ return super.compareTo(other);
+ }
+ if (!schemas.equals(other.schemas)) {
+ return schemas.compareTo(other.schemas);
+ }
+ return albums.compareTo(other.albums);
+ }
+}
diff --git a/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextSchema.java b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextSchema.java
new file mode 100644
index 000000000..852e3f552
--- /dev/null
+++ b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextSchema.java
@@ -0,0 +1,383 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.apex.model.contextmodel.concepts;
+
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Convert;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+import org.onap.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.apex.model.basicmodel.concepts.AxKey;
+import org.onap.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.apex.model.basicmodel.dao.converters.CDATAConditioner;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class holds a data schema definition in Apex. A data schema describes the structure of a
+ * single atom of data 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 complex data type such as a Java object or an object described
+ * using a data definition language such as Avro. The schema flavour defines the type of schema
+ * being defined and the schema itself defines the schema. The schema flavour is used by Apex to
+ * look up and load a plugin class that understands and interprets the schema definition and can
+ * create instances of classes for the schema.
+ * <p>
+ * An {@link AxContextSchema} is used to define each parameter in Apex events, the messages that
+ * enter, exit, and are passed internally in Apex. In addition, an Apex {@link AxContextAlbum}
+ * instances hold a map of {@link AxContextSchema} instances to represent the context being managed
+ * as an {@link AxContextAlbum}. For example, the state of all cells in a mobile network might be
+ * represented as an {@link AxContextAlbum} with its {@link AxContextSchema} being defined as @code
+ * cell} objects.
+ * <p>
+ * Validation checks that the schema key is not null. It also checks that the schema flavour is
+ * defined and matches the regular expression {@link SCHEMA_FLAVOUR_REGEXP}. Finally, validation
+ * checks that the defined schema is not a blank or empty string.
+ */
+@Entity
+@Table(name = "AxContextSchema")
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "apexContextSchema", namespace = "http://www.ericsson.com/apex")
+@XmlType(name = "AxContextSchema", namespace = "http://www.ericsson.com/apex",
+ propOrder = {"key", "schemaFlavour", "schemaDefinition"})
+
+public class AxContextSchema extends AxConcept {
+ private static final String SCHEMA_FLAVOUR = "schemaFlavour";
+ private static final String WHITESPACE_REGEXP = "\\s+$";
+
+ private static final long serialVersionUID = -6443016863162692288L;
+
+ /** Regular expression that constrains what values a schema flavour can have. */
+ public static final String SCHEMA_FLAVOUR_REGEXP = "[A-Za-z0-9\\-_]+";
+
+ /** An undefined schema flavour has this value. */
+ public static final String SCHEMA_FLAVOUR_UNDEFINED = "UNDEFINED";
+
+ /** The maximum permissible size of a schema definition. */
+ public static final int MAX_SCHEMA_SIZE = 32672; // The maximum size supported by Apache Derby
+
+ @EmbeddedId
+ @XmlElement(name = "key", required = true)
+ private AxArtifactKey key;
+
+ @Column(name = SCHEMA_FLAVOUR)
+ @XmlElement(required = true)
+ private String schemaFlavour;
+
+ @Column(name = "schemaDefinition", length = MAX_SCHEMA_SIZE)
+ @Convert(converter = CDATAConditioner.class)
+ @XmlJavaTypeAdapter(value = CDATAConditioner.class)
+ @XmlElement(name = "schemaDefinition", required = true)
+ private String schemaDefinition;
+
+ /**
+ * The default constructor creates a context schema with a null artifact key. The flavour of the
+ * context album is set as {@link SCHEMA_FLAVOUR_UNDEFINED} and the schema itself is defined as
+ * an empty string.
+ */
+ public AxContextSchema() {
+ this(new AxArtifactKey());
+ schemaFlavour = SCHEMA_FLAVOUR_UNDEFINED;
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxContextSchema(final AxContextSchema copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The key constructor creates a context schema with the given artifact key. The flavour of the
+ * context album is set as {@link SCHEMA_FLAVOUR_UNDEFINED} and the schema itself is defined as
+ * an empty string.
+ *
+ * @param key the key
+ */
+ public AxContextSchema(final AxArtifactKey key) {
+ this(key, SCHEMA_FLAVOUR_UNDEFINED, "");
+ }
+
+ /**
+ * This Constructor creates a context schema with all of its fields defined.
+ *
+ * @param key the key
+ * @param schemaFlavour the schema flavour
+ * @param schemaDefinition the schema definition
+ */
+ public AxContextSchema(final AxArtifactKey key, final String schemaFlavour, final String schemaDefinition) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(schemaFlavour, "schemaFlavour may not be null");
+ Assertions.argumentNotNull(schemaDefinition, "schemaDefinition may not be null");
+
+ this.key = key;
+ this.schemaFlavour = Assertions.validateStringParameter(SCHEMA_FLAVOUR, schemaFlavour, SCHEMA_FLAVOUR_REGEXP);
+ this.schemaDefinition = schemaDefinition.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ return key.getKeys();
+ }
+
+ /**
+ * Sets the key of the context schema.
+ *
+ * @param key the key of the context schema
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the schema flavour, which defines the schema definition type being used.
+ *
+ * @return the schema flavour
+ */
+ public String getSchemaFlavour() {
+ return schemaFlavour;
+ }
+
+ /**
+ * Sets the schema flavour, which defines the type of schema definition being used.
+ *
+ * @param schemaFlavour the schema flavour
+ */
+ public void setSchemaFlavour(final String schemaFlavour) {
+ this.schemaFlavour = Assertions.validateStringParameter(SCHEMA_FLAVOUR, schemaFlavour, SCHEMA_FLAVOUR_REGEXP);
+ }
+
+ /**
+ * Gets the schema, which defines the structure of this data schema atom.
+ *
+ * @return the schema definition
+ */
+ public String getSchema() {
+ return schemaDefinition;
+ }
+
+ /**
+ * Sets the schema, which defines the structure of this data schema atom.
+ *
+ * @param schema the schema definition
+ */
+ public void setSchema(final String schema) {
+ Assertions.argumentNotNull(schema, "schema may not be null");
+ this.schemaDefinition = schema.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#validate(com.ericsson.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (schemaFlavour.replaceAll(WHITESPACE_REGEXP, "").length() == 0
+ || schemaFlavour.equals(SCHEMA_FLAVOUR_UNDEFINED)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "schema flavour is not defined"));
+ }
+
+ try {
+ Assertions.validateStringParameter(SCHEMA_FLAVOUR, schemaFlavour, SCHEMA_FLAVOUR_REGEXP);
+ } catch (final IllegalArgumentException e) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "schema flavour invalid-" + e.getMessage()));
+ }
+
+ if (schemaDefinition.replaceAll(WHITESPACE_REGEXP, "").length() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "no schemaDefinition specified, schemaDefinition may not be blank"));
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ schemaFlavour = Assertions.validateStringParameter(SCHEMA_FLAVOUR, schemaFlavour, SCHEMA_FLAVOUR_REGEXP);
+ schemaDefinition = schemaDefinition.replaceAll(WHITESPACE_REGEXP, "");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",schemaFlavour=");
+ builder.append(schemaFlavour);
+ builder.append(",schemaDefinition=");
+ builder.append(schemaDefinition);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#copyTo(com.ericsson.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxContextSchema.class);
+
+ final AxContextSchema copy = ((AxContextSchema) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+ copy.setSchemaFlavour(schemaFlavour);
+ copy.setSchema(schemaDefinition);
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + schemaFlavour.hashCode();
+ result = prime * result + schemaDefinition.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxContextSchema other = (AxContextSchema) obj;
+
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ if (!schemaFlavour.equals(other.schemaFlavour)) {
+ return false;
+ }
+ final String thisSchema = CDATAConditioner.clean(schemaDefinition).replaceAll("\n", "");
+ final String otherSchema = CDATAConditioner.clean(other.schemaDefinition).replaceAll("\n", "");
+ return thisSchema.equals(otherSchema);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxContextSchema other = (AxContextSchema) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!schemaFlavour.equals(other.schemaFlavour)) {
+ return schemaFlavour.compareTo(other.schemaFlavour);
+ }
+ final String thisSchema = CDATAConditioner.clean(schemaDefinition).replaceAll("\n", "");
+ final String otherSchema = CDATAConditioner.clean(other.schemaDefinition).replaceAll("\n", "");
+ return thisSchema.compareTo(otherSchema);
+ }
+}
diff --git a/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextSchemas.java b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextSchemas.java
new file mode 100644
index 000000000..b4a7e4ada
--- /dev/null
+++ b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/AxContextSchemas.java
@@ -0,0 +1,424 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.apex.model.contextmodel.concepts;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javax.persistence.CascadeType;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.apex.model.basicmodel.concepts.AxConcept;
+import org.onap.apex.model.basicmodel.concepts.AxConceptGetter;
+import org.onap.apex.model.basicmodel.concepts.AxConceptGetterImpl;
+import org.onap.apex.model.basicmodel.concepts.AxKey;
+import org.onap.apex.model.basicmodel.concepts.AxValidationMessage;
+import org.onap.apex.model.basicmodel.concepts.AxValidationResult;
+import org.onap.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class is a context schema container and holds a map of the context schemas for an entire
+ * Apex model. All Apex models that use context schemas must have an {@link AxContextSchemas} field.
+ * The {@link AxContextSchemas} class implements the helper methods of the {@link AxConceptGetter}
+ * interface to allow {@link AxContextSchema} instances to be retrieved by calling methods directly
+ * on this class without referencing the contained map.
+ * <p>
+ * Validation checks that the container key is not null. An error is issued if no context schemas
+ * are defined in the container. Each context schema entry is checked to ensure that its key and
+ * value are not null and that the key matches the key in the map value. Each context schema entry
+ * is then validated individually.
+ */
+@Entity
+@Table(name = "AxContextSchemas")
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "AxContextSchemas", namespace = "http://www.ericsson.com/apex", propOrder = {"key", "schemas"})
+
+public class AxContextSchemas extends AxConcept implements AxConceptGetter<AxContextSchema> {
+ private static final long serialVersionUID = -3203734282886453582L;
+
+ @EmbeddedId
+ @XmlElement(name = "key", required = true)
+ private AxArtifactKey key;
+
+ // @formatter:off
+ @ManyToMany(cascade = CascadeType.ALL)
+ @JoinTable(
+ joinColumns = {@JoinColumn(name = "contextSchemasName", referencedColumnName = "name"),
+ @JoinColumn(name = "contextSchemasVersion", referencedColumnName = "version")},
+ inverseJoinColumns = {@JoinColumn(name = "contextSchemaName", referencedColumnName = "name"),
+ @JoinColumn(name = "contextSchemaVersion", referencedColumnName = "version")})
+ @XmlElement(name = "schemas", required = true)
+ private Map<AxArtifactKey, AxContextSchema> schemas;
+ // @formatter:on
+
+ /**
+ * The Default Constructor creates a {@link AxContextSchemas} object with a null artifact key
+ * and creates an empty context schemas map.
+ */
+ public AxContextSchemas() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public AxContextSchemas(final AxContextSchemas copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * The Key Constructor creates a {@link AxContextSchemas} object with the given artifact key and
+ * creates an empty context schemas map.
+ *
+ * @param key the key of the context album container
+ */
+ public AxContextSchemas(final AxArtifactKey key) {
+ this(key, new TreeMap<AxArtifactKey, AxContextSchema>());
+ }
+
+ /**
+ * This Constructor creates a {@link AxContextSchemas} object with all its fields defined.
+ *
+ * @param key the key of the context schema container
+ * @param schemas a map of the schemas to insert in the context schema container
+ */
+ public AxContextSchemas(final AxArtifactKey key, final Map<AxArtifactKey, AxContextSchema> schemas) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(schemas, "schemas may not be null");
+
+ this.key = key;
+ this.schemas = new TreeMap<>();
+ this.schemas.putAll(schemas);
+ }
+
+ /**
+ * When a model is unmarshalled from disk or from the database, the context schema map is
+ * returned as a raw hash map. This method is called by JAXB after unmarshaling and is used to
+ * convert the hash map to a {@link NavigableMap} so that it will work with the
+ * {@link AxConceptGetter} interface.
+ *
+ * @param u the unmarshaler that is unmarshaling the model
+ * @param parent the parent object of this object in the unmarshaler
+ */
+ public void afterUnmarshal(final Unmarshaller u, final Object parent) {
+ // The map must be navigable to allow name and version searching, unmarshaling returns a
+ // hash map
+ final NavigableMap<AxArtifactKey, AxContextSchema> navigableContextSchemas = new TreeMap<>();
+ navigableContextSchemas.putAll(schemas);
+ schemas = navigableContextSchemas;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+ keyList.addAll(schemas.keySet());
+
+ return keyList;
+ }
+
+ /**
+ * Sets the key of the context schema container.
+ *
+ * @param key the key of the container
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the map of context schemas in this container.
+ *
+ * @return the map of schemas
+ */
+ public Map<AxArtifactKey, AxContextSchema> getSchemasMap() {
+ return schemas;
+ }
+
+ /**
+ * Sets the map of context schemas in this container.
+ *
+ * @param schemasMap the map of schemas
+ */
+ public void setSchemasMap(final Map<AxArtifactKey, AxContextSchema> schemasMap) {
+ Assertions.argumentNotNull(schemasMap, "schemasMap may not be null");
+
+ this.schemas = new TreeMap<>();
+ this.schemas.putAll(schemasMap);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#validate(com.ericsson.apex.model.
+ * basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+
+ if (schemas.size() == 0) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "contextSchemas may not be empty"));
+ } else {
+ for (final Entry<AxArtifactKey, AxContextSchema> contextSchemaEntry : schemas.entrySet()) {
+ if (contextSchemaEntry.getKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key on schemas entry " + contextSchemaEntry.getKey() + " may not be the null key"));
+ } else if (contextSchemaEntry.getValue() == null) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "value on schemas entry " + contextSchemaEntry.getKey() + " may not be null"));
+ } else {
+ if (!contextSchemaEntry.getKey().equals(contextSchemaEntry.getValue().getKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(),
+ ValidationResult.INVALID, "key on schemas entry " + contextSchemaEntry.getKey()
+ + " does not equal entry key " + contextSchemaEntry.getValue().getKey()));
+ }
+
+ result = contextSchemaEntry.getValue().validate(result);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ for (final Entry<AxArtifactKey, AxContextSchema> contextSchemaEntry : schemas.entrySet()) {
+ contextSchemaEntry.getKey().clean();
+ contextSchemaEntry.getValue().clean();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",schemas=");
+ builder.append(schemas);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#copyTo(com.ericsson.apex.model.
+ * basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxContextSchemas.class);
+
+ final AxContextSchemas copy = ((AxContextSchemas) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+
+ final Map<AxArtifactKey, AxContextSchema> newcontextSchemas = new TreeMap<>();
+ for (final Entry<AxArtifactKey, AxContextSchema> contextSchemasEntry : schemas.entrySet()) {
+ newcontextSchemas.put(new AxArtifactKey(contextSchemasEntry.getKey()),
+ new AxContextSchema(contextSchemasEntry.getValue()));
+ }
+ copy.setSchemasMap(newcontextSchemas);
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + schemas.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxContextSchemas other = (AxContextSchemas) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return schemas.equals(other.schemas);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxContextSchemas other = (AxContextSchemas) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ if (!schemas.equals(other.schemas)) {
+ return (schemas.hashCode() - other.schemas.hashCode());
+ }
+
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.core.basicmodel.concepts.AxConceptGetter#get(com.ericsson.apex.core.
+ * basicmodel.concepts.AxArtifactKey)
+ */
+ @Override
+ public AxContextSchema get(final AxArtifactKey conceptKey) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKey);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.core.basicmodel.concepts.AxConceptGetter#get(java.lang.String)
+ */
+ @Override
+ public AxContextSchema get(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKeyName);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.core.basicmodel.concepts.AxConceptGetter#get(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public AxContextSchema get(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).get(conceptKeyName,
+ conceptKeyVersion);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.core.basicmodel.concepts.AxConceptGetter#getAll(java.lang.String)
+ */
+ @Override
+ public Set<AxContextSchema> getAll(final String conceptKeyName) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).getAll(conceptKeyName);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.core.basicmodel.concepts.AxConceptGetter#getAll(java.lang.String,
+ * java.lang.String)
+ */
+ @Override
+ public Set<AxContextSchema> getAll(final String conceptKeyName, final String conceptKeyVersion) {
+ return new AxConceptGetterImpl<>((NavigableMap<AxArtifactKey, AxContextSchema>) schemas).getAll(conceptKeyName,
+ conceptKeyVersion);
+ }
+}
diff --git a/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/package-info.java b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/package-info.java
new file mode 100644
index 000000000..f89f2f803
--- /dev/null
+++ b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/concepts/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Contains the concepts required to manage context in APEX. It defines the main APEX concepts of
+ * Context Schemas and Context Albums.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.apex.model.contextmodel.concepts;
diff --git a/model/context-model/src/main/java/org/onap/apex/model/contextmodel/handling/ContextComparer.java b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/handling/ContextComparer.java
new file mode 100644
index 000000000..8d654be74
--- /dev/null
+++ b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/handling/ContextComparer.java
@@ -0,0 +1,70 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.apex.model.contextmodel.handling;
+
+import org.onap.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.apex.model.contextmodel.concepts.AxContextAlbum;
+import org.onap.apex.model.contextmodel.concepts.AxContextAlbums;
+import org.onap.apex.model.contextmodel.concepts.AxContextSchema;
+import org.onap.apex.model.contextmodel.concepts.AxContextSchemas;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapComparer;
+import org.onap.policy.apex.model.utilities.comparison.KeyedMapDifference;
+
+/**
+ * This class compares the context in two AxContext objects and returns the differences. The
+ * differences are returned in a {@link KeyedMapDifference} object that contains the left, equal,
+ * and right context schemas or albums.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public class ContextComparer {
+
+ /**
+ * Compare two {@link AxContextAlbums} objects, comparing their context albums one after
+ * another.
+ *
+ * @param left the left context
+ * @param right the right context
+ * @return the difference
+ */
+ public KeyedMapDifference<AxArtifactKey, AxContextAlbum> compare(final AxContextAlbums left,
+ final AxContextAlbums right) {
+ // Find the difference between the AxContext objects
+ return new KeyedMapComparer<AxArtifactKey, AxContextAlbum>().compareMaps(left.getAlbumsMap(),
+ right.getAlbumsMap());
+ }
+
+ /**
+ * Compare two {@link AxContextSchema} objects, comparing their context schemas one after
+ * another.
+ *
+ * @param left the left context
+ * @param right the right context
+ * @return the difference
+ */
+ public KeyedMapDifference<AxArtifactKey, AxContextSchema> compare(final AxContextSchemas left,
+ final AxContextSchemas right) {
+ // Find the difference between the AxContext objects
+ return new KeyedMapComparer<AxArtifactKey, AxContextSchema>().compareMaps(left.getSchemasMap(),
+ right.getSchemasMap());
+ }
+
+}
diff --git a/model/context-model/src/main/java/org/onap/apex/model/contextmodel/handling/package-info.java b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/handling/package-info.java
new file mode 100644
index 000000000..bfc44f7e0
--- /dev/null
+++ b/model/context-model/src/main/java/org/onap/apex/model/contextmodel/handling/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Provides some helper classes for handling context, including a utility class for comparing two
+ * context objects.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+package org.onap.apex.model.contextmodel.handling;