Java 17 Upgrade
[policy/models.git] / models-tosca / src / main / java / org / onap / policy / models / tosca / simple / concepts / JpaToscaEntityType.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019-2020, 2022-2023 Nordix Foundation.
4  *  Modifications Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.models.tosca.simple.concepts;
23
24 import jakarta.persistence.AttributeOverride;
25 import jakarta.persistence.Column;
26 import jakarta.persistence.ElementCollection;
27 import jakarta.persistence.EmbeddedId;
28 import jakarta.persistence.Lob;
29 import jakarta.persistence.MappedSuperclass;
30 import jakarta.ws.rs.core.Response;
31 import java.io.Serial;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Map.Entry;
35 import java.util.TreeMap;
36 import lombok.Data;
37 import lombok.EqualsAndHashCode;
38 import lombok.NonNull;
39 import org.apache.commons.lang3.ObjectUtils;
40 import org.onap.policy.common.parameters.annotations.NotBlank;
41 import org.onap.policy.common.parameters.annotations.NotNull;
42 import org.onap.policy.common.utils.coder.CoderException;
43 import org.onap.policy.common.utils.coder.StandardCoder;
44 import org.onap.policy.models.base.PfAuthorative;
45 import org.onap.policy.models.base.PfConcept;
46 import org.onap.policy.models.base.PfConceptKey;
47 import org.onap.policy.models.base.PfKey;
48 import org.onap.policy.models.base.PfModelRuntimeException;
49 import org.onap.policy.models.base.PfUtils;
50 import org.onap.policy.models.base.validation.annotations.VerifyKey;
51 import org.onap.policy.models.tosca.authorative.concepts.ToscaEntity;
52
53 /**
54  * Class to represent the EntrySchema of list/map property in TOSCA definition.
55  */
56 @MappedSuperclass
57 @Data
58 @EqualsAndHashCode(callSuper = false)
59 public class JpaToscaEntityType<T extends ToscaEntity> extends PfConcept implements PfAuthorative<T> {
60     @Serial
61     private static final long serialVersionUID = -1330661834220739393L;
62
63     private static final StandardCoder STANDARD_CODER = new StandardCoder();
64
65     @EmbeddedId
66     @VerifyKey
67     @NotNull
68     private PfConceptKey key;
69
70     // @formatter:off
71     @Column
72     @AttributeOverride(name = "name", column = @Column(name = "derived_from_name"))
73     @AttributeOverride(name = "version", column = @Column(name = "derived_from_version"))
74     @VerifyKey
75     private PfConceptKey derivedFrom;
76
77     @ElementCollection
78     @Lob
79     private Map<@NotNull @NotBlank String, @NotNull @NotBlank String> metadata;
80
81     @Column
82     @NotBlank
83     private String description;
84
85     private transient T toscaEntity;
86     // @formatter:on
87
88     /**
89      * The Default Constructor creates a {@link JpaToscaEntityType} object with a null key.
90      */
91     public JpaToscaEntityType() {
92         this(new PfConceptKey());
93     }
94
95     /**
96      * The Key Constructor creates a {@link JpaToscaEntityType} object with the given concept key.
97      *
98      * @param key the key
99      */
100     public JpaToscaEntityType(@NonNull final PfConceptKey key) {
101         this.key = key;
102     }
103
104     /**
105      * Copy constructor.
106      *
107      * @param copyConcept the concept to copy from
108      */
109     public JpaToscaEntityType(final JpaToscaEntityType<T> copyConcept) {
110         super(copyConcept);
111         this.key = new PfConceptKey(copyConcept.key);
112         this.derivedFrom = (copyConcept.derivedFrom != null ? new PfConceptKey(copyConcept.derivedFrom) : null);
113         this.metadata = (copyConcept.metadata != null ? new TreeMap<>(copyConcept.metadata) : null);
114         this.description = copyConcept.description;
115     }
116
117     /**
118      * Authorative constructor.
119      *
120      * @param authorativeConcept the authorative concept to copy from
121      */
122     public JpaToscaEntityType(final T authorativeConcept) {
123         this.fromAuthorative(authorativeConcept);
124     }
125
126     @Override
127     public T toAuthorative() {
128         toscaEntity.setName(getKey().getName());
129         toscaEntity.setVersion(getKey().getVersion());
130
131         if (derivedFrom != null) {
132             toscaEntity.setDerivedFrom(derivedFrom.getName());
133         }
134
135         if (description != null) {
136             toscaEntity.setDescription(description);
137         }
138
139         toscaEntity.setMetadata(PfUtils.mapMap(metadata, this::deserializeMetadataValue));
140
141         return toscaEntity;
142     }
143
144     @Override
145     public void fromAuthorative(T toscaEntity) {
146         key = new PfConceptKey();
147
148         if (toscaEntity.getName() != null) {
149             key.setName(toscaEntity.getName());
150         }
151
152         if (toscaEntity.getVersion() != null) {
153             key.setVersion(toscaEntity.getVersion());
154         }
155
156         if (toscaEntity.getDerivedFrom() != null) {
157             // Check if the derived from field contains a name-version ID
158             if (toscaEntity.getDerivedFrom().contains(":")) {
159                 derivedFrom = new PfConceptKey(toscaEntity.getDerivedFrom());
160             } else {
161                 derivedFrom = new PfConceptKey(toscaEntity.getDerivedFrom(), PfKey.NULL_KEY_VERSION);
162             }
163         }
164
165         if (toscaEntity.getDescription() != null) {
166             description = toscaEntity.getDescription();
167         }
168
169         metadata = PfUtils.mapMap(toscaEntity.getMetadata(), this::serializeMetadataValue);
170     }
171
172     @Override
173     public List<PfKey> getKeys() {
174         final List<PfKey> keyList = getKey().getKeys();
175         if (derivedFrom != null) {
176             keyList.addAll(derivedFrom.getKeys());
177         }
178         return keyList;
179     }
180
181     @Override
182     public void clean() {
183         key.clean();
184
185         if (derivedFrom != null) {
186             derivedFrom.clean();
187         }
188
189         if (metadata != null) {
190             for (Entry<String, String> metadataEntry : metadata.entrySet()) {
191                 metadataEntry.setValue(metadataEntry.getValue().trim());
192             }
193         }
194
195         description = (description != null ? description.trim() : null);
196     }
197
198     @Override
199     public int compareTo(final PfConcept otherConcept) {
200         if (otherConcept == null) {
201             return -1;
202         }
203         if (this == otherConcept) {
204             return 0;
205         }
206         if (getClass() != otherConcept.getClass()) {
207             return getClass().getName().compareTo(otherConcept.getClass().getName());
208         }
209
210         @SuppressWarnings("unchecked")
211         final JpaToscaEntityType<T> other = (JpaToscaEntityType<T>) otherConcept;
212
213         int result = key.compareTo(other.key);
214         if (result != 0) {
215             return result;
216         }
217
218         result = ObjectUtils.compare(derivedFrom, other.derivedFrom);
219         if (result != 0) {
220             return result;
221         }
222
223         result = PfUtils.compareMaps(metadata, other.metadata);
224         if (result != 0) {
225             return result;
226         }
227
228         return ObjectUtils.compare(description, other.description);
229     }
230
231     protected Object deserializeMetadataValue(String metadataValue) {
232         try {
233             return STANDARD_CODER.decode(metadataValue, Object.class);
234         } catch (CoderException ce) {
235             String errorMessage = "error decoding metadata JSON value read from database: " + metadataValue;
236             throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage, ce);
237         }
238     }
239
240     protected String serializeMetadataValue(Object metadataValue) {
241         try {
242             return STANDARD_CODER.encode(metadataValue);
243         } catch (CoderException ce) {
244             String errorMessage = "error encoding metadata JSON value for database: " + metadataValue;
245             throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, errorMessage, ce);
246         }
247     }
248 }