/*-
* ============LICENSE_START=======================================================
* Copyright (C) 2016-2018 Ericsson. All rights reserved.
* Modifications Copyright (C) 2019 Nordix Foundation.
* ================================================================================
* 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.policy.apex.model.policymodel.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.Enumerated;
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.policy.apex.model.basicmodel.concepts.AxArtifactKey;
import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
import org.onap.policy.apex.model.basicmodel.concepts.AxKeyUse;
import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
import org.onap.policy.apex.model.basicmodel.concepts.AxValidationMessage;
import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
import org.onap.policy.common.utils.validation.Assertions;
/**
* This class defines the type of output handling that will be used when a task in a state completes
* execution. Each task {@link AxTask} in a state {@link AxState} must select a state output
* {@link AxStateOutput} in order to pass its fields to an output event. Therefore, each task has an
* associated instance of this class that defines how the state output of the state is selected and
* how the output fields of the task are marshaled onto the fields of the output event. A
* {@link AxStateTaskReference} instance defines the task output handling as either
* {@link AxStateTaskOutputType#DIRECT} or {@link AxStateTaskOutputType#LOGIC}. In the case of
* {@link AxStateTaskOutputType#DIRECT} output selection, the output reference key held in this
* {@link AxStateTaskReference} instance to an instance of an {@link AxStateOutput} class. In the
* case of {@link AxStateTaskOutputType#LOGIC} output selection, the output reference key held in
* this {@link AxStateTaskReference} instance to an instance of an {@link AxStateFinalizerLogic}
* class. See the explanation in the {@link AxState} class for a full description of this handling.
*
*
During validation of a state task reference, the validation checks listed below are executed:
*
* - The state task reference key must not be a null key and must be valid, see validation in
* {@link AxReferenceKey}
*
- The output type must be defined, that is not equal to {@link AxStateTaskOutputType#UNDEFINED}
*
- The output key must not be a null key and must be valid, see validation in
* {@link AxReferenceKey}
*
*/
@Entity
@Table(name = "AxStateTaskReference")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "apexStateTaskReference", namespace = "http://www.onap.org/policy/apex-pdp")
@XmlType(name = "AxStateTaskReference", namespace = "http://www.onap.org/policy/apex-pdp",
propOrder = {"key", "outputType", "output"})
public class AxStateTaskReference extends AxConcept {
private static final long serialVersionUID = 8041771382337655535L;
@EmbeddedId
@XmlElement(name = "key", required = true)
private AxReferenceKey key;
@Enumerated
@Column(name = "outputType")
@XmlElement(required = true)
private AxStateTaskOutputType outputType;
// @formatter:off
@Embedded
@AttributeOverrides({@AttributeOverride(name = "parentKeyName", column = @Column(name = "outputParentKeyName")),
@AttributeOverride(name = "parentKeyVersion", column = @Column(name = "outputParentKeyVersion")),
@AttributeOverride(name = "parentLocalName", column = @Column(name = "outputParentLocalName")),
@AttributeOverride(name = "localName", column = @Column(name = "outputLocalName"))})
@Column(name = "output")
@XmlElement(required = true)
private AxReferenceKey output;
// @formatter:on
/**
* The Default Constructor creates a state task reference with a null reference key, an
* undefined output type and a null output reference key.
*/
public AxStateTaskReference() {
this(new AxReferenceKey());
}
/**
* Copy constructor.
*
* @param copyConcept the concept to copy from
*/
public AxStateTaskReference(final AxStateTaskReference copyConcept) {
super(copyConcept);
}
/**
* The Keyed Constructor creates a state task reference with the given reference key, an
* undefined output type and a null output reference key.
*
* @param key the key
*/
public AxStateTaskReference(final AxReferenceKey key) {
this(key, // Key
AxStateTaskOutputType.UNDEFINED, // Output type
AxReferenceKey.getNullKey()); // Output
}
/**
* This Constructor creates a state task reference instance with a reference key composed from
* the given parent key with a local name composed by concatenating the name of the task key
* with the local name of the output. The output type and output are set to the given values.
*
* @param parentKey the parent key to use for the key of the state task reference
* @param taskKey the task key to use for the first part of the state task reference local name
* @param outputType the type of output to perform when this state task reference instance is
* used
* @param output the output to perform when this state task reference instance is used
*/
public AxStateTaskReference(final AxReferenceKey parentKey, final AxArtifactKey taskKey,
final AxStateTaskOutputType outputType, final AxReferenceKey output) {
this(new AxReferenceKey(parentKey, taskKey.getName() + '_' + outputType.name() + '_' + output.getLocalName()),
outputType, output);
}
/**
* This Constructor creates a state task reference instance with the given reference key and all
* its fields defined.
*
* @param key the key of the state task reference
* @param outputType the type of output to perform when this state task reference instance is
* used
* @param output the output to perform when this state task reference instance is used
*/
public AxStateTaskReference(final AxReferenceKey key, final AxStateTaskOutputType outputType,
final AxReferenceKey output) {
super();
Assertions.argumentNotNull(key, "key may not be null");
Assertions.argumentNotNull(outputType, "outputType may not be null");
Assertions.argumentNotNull(output, "output may not be null");
this.key = key;
this.outputType = outputType;
this.output = output;
}
/**
* {@inheritDoc}.
*/
@Override
public AxReferenceKey getKey() {
return key;
}
/**
* {@inheritDoc}.
*/
@Override
public List getKeys() {
final List keyList = key.getKeys();
if (!output.equals(AxReferenceKey.getNullKey())) {
keyList.add(new AxKeyUse(output));
}
return keyList;
}
/**
* Sets the key of the state task reference.
*
* @param key the key of the state task reference
*/
public void setKey(final AxReferenceKey key) {
Assertions.argumentNotNull(key, "key may not be null");
this.key = key;
}
/**
* Gets the type of output to perform when this state task reference instance is used.
*
* @return the the type of output to perform when this state task reference instance is used
*/
public AxStateTaskOutputType getStateTaskOutputType() {
return outputType;
}
/**
* Sets the type of output to perform when this state task reference instance is used.
*
* @param stateTaskOutputType the type of output to perform when this state task reference
* instance is used
*/
public void setStateTaskOutputType(final AxStateTaskOutputType stateTaskOutputType) {
Assertions.argumentNotNull(stateTaskOutputType, "outputType may not be null");
this.outputType = stateTaskOutputType;
}
/**
* Gets the output to perform when this state task reference instance is used.
*
* @return the output to perform when this state task reference instance is used
*/
public AxReferenceKey getOutput() {
return output;
}
/**
* Sets the output to perform when this state task reference instance is used.
*
* @param output the output to perform when this state task reference instance is used
*/
public void setOutput(final AxReferenceKey output) {
Assertions.argumentNotNull(output, "output may not be null");
this.output = output;
}
/**
* {@inheritDoc}.
*/
@Override
public AxValidationResult validate(final AxValidationResult resultIn) {
AxValidationResult result = resultIn;
if (key.equals(AxReferenceKey.getNullKey())) {
result.addValidationMessage(
new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
}
result = key.validate(result);
if (outputType == AxStateTaskOutputType.UNDEFINED) {
result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
"outputType may not be UNDEFINED"));
}
if (output.equals(AxReferenceKey.getNullKey())) {
result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
"output key " + output.getId() + " is a null key"));
}
result = output.validate(result);
return result;
}
/**
* {@inheritDoc}.
*/
@Override
public void clean() {
key.clean();
output.clean();
}
/**
* {@inheritDoc}.
*/
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append(this.getClass().getSimpleName());
builder.append(":(");
builder.append("stateKey=");
builder.append(key);
builder.append(",outputType=");
builder.append(outputType);
builder.append(",output=");
builder.append(output);
builder.append(")");
return builder.toString();
}
/**
* {@inheritDoc}.
*/
@Override
public AxConcept copyTo(final AxConcept targetObject) {
Assertions.argumentNotNull(targetObject, "target may not be null");
final Object copyObject = targetObject;
Assertions.instanceOf(copyObject, AxStateTaskReference.class);
final AxStateTaskReference copy = ((AxStateTaskReference) copyObject);
copy.setKey(new AxReferenceKey(key));
copy.setStateTaskOutputType(AxStateTaskOutputType.valueOf(outputType.name()));
copy.setOutput(output);
return copy;
}
/**
* {@inheritDoc}.
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + key.hashCode();
result = prime * result + outputType.hashCode();
result = prime * result + output.hashCode();
return result;
}
/**
* {@inheritDoc}.
*/
@Override
public boolean equals(final Object obj) {
if (obj == null) {
return false;
}
if (this == obj) {
return true;
}
if (getClass() != obj.getClass()) {
return false;
}
final AxStateTaskReference other = (AxStateTaskReference) obj;
if (!key.equals(other.key)) {
return false;
}
if (outputType != other.outputType) {
return false;
}
return output.equals(other.output);
}
/**
* {@inheritDoc}.
*/
@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 AxStateTaskReference other = (AxStateTaskReference) otherObj;
if (!key.equals(other.key)) {
return key.compareTo(other.key);
}
if (!outputType.equals(other.outputType)) {
return outputType.compareTo(other.outputType);
}
return output.compareTo(other.output);
}
}