Json Serialization should hide "empty".
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / servlets / RepresentationUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.be.servlets;
22
23 import com.fasterxml.jackson.annotation.JsonFilter;
24 import com.fasterxml.jackson.annotation.JsonInclude;
25 import com.fasterxml.jackson.databind.DeserializationFeature;
26 import com.fasterxml.jackson.databind.ObjectMapper;
27 import com.fasterxml.jackson.databind.SerializationFeature;
28 import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter.SerializeExceptFilter;
29 import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
30 import com.google.common.collect.ImmutableMap;
31 import com.google.gson.Gson;
32 import com.google.gson.JsonElement;
33 import com.google.gson.JsonObject;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.Collection;
37 import java.util.HashMap;
38 import java.util.HashSet;
39 import java.util.List;
40 import java.util.Set;
41 import org.openecomp.sdc.be.config.BeEcompErrorManager;
42 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
43 import org.openecomp.sdc.be.model.ArtifactDefinition;
44 import org.openecomp.sdc.be.model.InterfaceDefinition;
45 import org.openecomp.sdc.be.model.Operation;
46 import org.openecomp.sdc.be.model.Resource;
47 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
48 import org.openecomp.sdc.common.api.Constants;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 public class RepresentationUtils {
53
54     private static final Logger log = LoggerFactory.getLogger(RepresentationUtils.class);
55
56     public static ArtifactDefinition convertJsonToArtifactDefinitionForUpdate(String content, Class<ArtifactDefinition> clazz) {
57
58         JsonObject jsonElement = new JsonObject();
59         ArtifactDefinition resourceInfo = null;
60
61         try {
62             Gson gson = new Gson();
63             jsonElement = gson.fromJson(content, jsonElement.getClass());
64             String payload = null;
65             jsonElement.remove(Constants.ARTIFACT_GROUP_TYPE);
66             //in update the group type is ignored but this spagheti code makes it too complex to remove this field.
67             jsonElement.addProperty(Constants.ARTIFACT_GROUP_TYPE, ArtifactGroupTypeEnum.INFORMATIONAL.getType());
68             JsonElement artifactPayload = jsonElement.get(Constants.ARTIFACT_PAYLOAD_DATA);
69             if (artifactPayload != null && !artifactPayload.isJsonNull()) {
70                 payload = artifactPayload.getAsString();
71             }
72             jsonElement.remove(Constants.ARTIFACT_PAYLOAD_DATA);
73             String json = gson.toJson(jsonElement);
74             ObjectMapper mapper = new ObjectMapper();
75             mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
76             mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
77             mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
78
79             resourceInfo = mapper.readValue(json, clazz);
80             resourceInfo.setPayloadData(payload);
81
82         } catch (Exception e) {
83             BeEcompErrorManager.getInstance().logBeArtifactInformationInvalidError("Artifact Upload / Update");
84             log.debug("Failed to convert the content {} to object.", content.substring(0, Math.min(50, content.length())), e);
85         }
86
87         return resourceInfo;
88     }
89
90
91     public static class ResourceRep {
92
93     }
94
95     /**
96      * Build Representation of given Object
97      *
98      * @param elementToRepresent
99      * @return
100      * @throws IOException
101      */
102     public static <T> Object toRepresentation(T elementToRepresent) throws IOException {
103         ObjectMapper mapper = new ObjectMapper();
104         mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
105         mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
106         return mapper.writeValueAsString(elementToRepresent);
107     }
108
109
110
111
112     public static <T> T fromRepresentation(String json, Class<T> clazz) {
113         ObjectMapper mapper = new ObjectMapper();
114         T object = null;
115         mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
116         mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
117         mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
118         try {
119             object = mapper.readValue(json, clazz);
120         } catch (Exception e) {
121             log.error("Error when parsing JSON of object of type {}", clazz.getSimpleName(), e);
122         } // return null in case of exception
123
124         return object;
125     }
126
127
128     public static ArtifactDefinition convertJsonToArtifactDefinition(String content, Class<ArtifactDefinition> clazz) {
129
130         JsonObject jsonElement = new JsonObject();
131         ArtifactDefinition resourceInfo = null;
132
133         try {
134             Gson gson = new Gson();
135             jsonElement = gson.fromJson(content, jsonElement.getClass());
136             JsonElement artifactGroupValue = jsonElement.get(Constants.ARTIFACT_GROUP_TYPE);
137             if (artifactGroupValue != null && !artifactGroupValue.isJsonNull()) {
138                 String groupValueUpper = artifactGroupValue.getAsString().toUpperCase();
139                 if (!ArtifactGroupTypeEnum.getAllTypes().contains(groupValueUpper)) {
140                     StringBuilder sb = new StringBuilder();
141                     for (String value : ArtifactGroupTypeEnum.getAllTypes()) {
142                         sb.append(value).append(", ");
143                     }
144                     log.debug("artifactGroupType is {}. valid values are: {}", groupValueUpper, sb);
145                     return null;
146                 } else {
147                     jsonElement.remove(Constants.ARTIFACT_GROUP_TYPE);
148                     jsonElement.addProperty(Constants.ARTIFACT_GROUP_TYPE, groupValueUpper);
149                 }
150             }
151             String payload = null;
152             JsonElement artifactPayload = jsonElement.get(Constants.ARTIFACT_PAYLOAD_DATA);
153             if (artifactPayload != null && !artifactPayload.isJsonNull()) {
154                 payload = artifactPayload.getAsString();
155             }
156             jsonElement.remove(Constants.ARTIFACT_PAYLOAD_DATA);
157             String json = gson.toJson(jsonElement);
158             ObjectMapper mapper = new ObjectMapper();
159             mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
160             mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
161             mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
162
163             resourceInfo = mapper.readValue(json, clazz);
164             resourceInfo.setPayloadData(payload);
165
166         } catch (Exception e) {
167             BeEcompErrorManager.getInstance().logBeArtifactInformationInvalidError("Artifact Upload / Update");
168             log.debug("Failed to convert the content {} to object.", content.substring(0, Math.min(50, content.length())), e);
169         }
170
171         return resourceInfo;
172     }
173
174     public static <T> Object toFilteredRepresentation(T elementToRepresent) throws IOException {
175         ObjectMapper mapper = new ObjectMapper();
176         mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
177         mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
178         mapper.setMixIns(IS_EMPTY_FILTER_MIXIN);
179         return mapper.writer(new SimpleFilterProvider().addFilter(REMOVE_IS_EMPTY_FROM_COLLECTIONS_FILTER,
180             SerializeExceptFilter.serializeAllExcept(EMPTY))).writeValueAsString(elementToRepresent);
181     }
182
183     @JsonFilter(REMOVE_IS_EMPTY_FROM_COLLECTIONS_FILTER)
184     private static class IsEmptyFilterMixIn {}
185
186     private static final String EMPTY = "empty";
187     private static final String REMOVE_IS_EMPTY_FROM_COLLECTIONS_FILTER = "removeIsEmptyFromCollections";
188     private static final ImmutableMap<Class<?>,Class<?>> IS_EMPTY_FILTER_MIXIN =
189         ImmutableMap.<Class<?>,Class<?>>builder()
190             .put(Collection.class,IsEmptyFilterMixIn.class)
191             .put(List.class,IsEmptyFilterMixIn.class)
192             .put(Set.class,IsEmptyFilterMixIn.class)
193             .put(HashMap.class,IsEmptyFilterMixIn.class)
194             .put(ArrayList.class,IsEmptyFilterMixIn.class)
195             .put(HashSet.class,IsEmptyFilterMixIn.class)
196             .put(InterfaceDefinition.class,IsEmptyFilterMixIn.class)
197             .put(Operation.class,IsEmptyFilterMixIn.class)
198             .put(Resource.class,IsEmptyFilterMixIn.class)
199             .put(ToscaDataDefinition.class,IsEmptyFilterMixIn.class).build();
200
201 }