1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.handler.mediasource.ngdm.impl.metadata;
21
22 import static com.day.cq.dam.api.DamConstants.TIFF_IMAGELENGTH;
23 import static com.day.cq.dam.api.DamConstants.TIFF_IMAGEWIDTH;
24
25 import java.util.Collections;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Objects;
29 import java.util.TreeMap;
30 import java.util.stream.Collectors;
31
32 import org.apache.commons.lang3.StringUtils;
33 import org.apache.commons.lang3.builder.ToStringBuilder;
34 import org.apache.sling.api.resource.ValueMap;
35 import org.apache.sling.api.wrappers.ValueMapDecorator;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.annotations.Nullable;
38
39 import com.fasterxml.jackson.core.JsonProcessingException;
40 import com.fasterxml.jackson.databind.json.JsonMapper;
41
42 import io.wcm.handler.media.Dimension;
43 import io.wcm.handler.mediasource.ngdm.impl.metadata.MetadataResponse.RepositoryMetadata;
44 import io.wcm.wcm.commons.contenttype.ContentType;
45 import io.wcm.wcm.commons.util.ToStringStyle;
46
47
48
49
50 public final class NextGenDynamicMediaMetadata {
51
52 private final String mimeType;
53 private final Long fileSize;
54 private final Dimension dimension;
55 private final String assetStatus;
56 private final ValueMap properties;
57 private final List<SmartCrop> smartCrops;
58
59 private static final JsonMapper OBJECT_MAPPER = new JsonMapper();
60 static final String RT_RENDITION_SMARTCROP = "dam/rendition/smartcrop";
61
62 NextGenDynamicMediaMetadata(@Nullable String mimeType, @Nullable Long fileSize, @Nullable Dimension dimension,
63 @Nullable String assetStatus, @Nullable ValueMap properties, @Nullable List<SmartCrop> smartCrops) {
64 this.mimeType = mimeType;
65 this.fileSize = fileSize;
66 this.dimension = dimension;
67 this.assetStatus = assetStatus;
68 if (properties != null) {
69 this.properties = properties;
70 }
71 else {
72 this.properties = ValueMap.EMPTY;
73 }
74 if (smartCrops != null) {
75 this.smartCrops = smartCrops;
76 }
77 else {
78 this.smartCrops = Collections.emptyList();
79 }
80 }
81
82
83
84
85 public @NotNull String getMimeType() {
86 return Objects.toString(mimeType, ContentType.OCTET_STREAM);
87 }
88
89
90
91
92 public @Nullable Long getFileSize() {
93 return fileSize;
94 }
95
96
97
98
99 public @Nullable Dimension getDimension() {
100 return dimension;
101 }
102
103
104
105
106 public String getAssetStatus() {
107 return this.assetStatus;
108 }
109
110
111
112
113 public ValueMap getProperties() {
114 return properties;
115 }
116
117
118
119
120 public List<SmartCrop> getSmartCrops() {
121 return Collections.unmodifiableList(smartCrops);
122 }
123
124
125
126
127 public boolean isValid() {
128 return mimeType != null;
129 }
130
131 @Override
132 public String toString() {
133 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_OMIT_NULL_STYLE)
134 .append("mimeType", mimeType)
135 .append("fileSize", fileSize)
136 .append("dimension", dimension)
137 .append("assetStatus", assetStatus)
138 .append("properties", properties.isEmpty() ? null : new TreeMap<String, Object>(properties))
139 .append("smartCrops", smartCrops.isEmpty() ? null : smartCrops)
140 .toString();
141 }
142
143
144
145
146
147
148
149 @SuppressWarnings("null")
150 public static @NotNull NextGenDynamicMediaMetadata fromJson(@NotNull String jsonResponse) throws JsonProcessingException {
151 MetadataResponse response = OBJECT_MAPPER.readValue(jsonResponse, MetadataResponse.class);
152 RepositoryMetadata respositoryMetadata = response.repositoryMetadata;
153 Map<String, Object> assetMetadata = response.assetMetadata;
154 ValueMap properties = null;
155
156 long width = 0;
157 long height = 0;
158 String assetStatus = null;
159 if (assetMetadata != null) {
160 properties = new ValueMapDecorator(assetMetadata);
161 width = properties.get(TIFF_IMAGEWIDTH, 0L);
162 height = properties.get(TIFF_IMAGELENGTH, 0L);
163 assetStatus = properties.get("dam:assetStatus", String.class);
164 }
165 Dimension dimension = toDimension(width, height);
166
167 String mimeType = null;
168 Long fileSize = null;
169 List<SmartCrop> smartCrops = null;
170 if (respositoryMetadata != null) {
171 mimeType = respositoryMetadata.dcFormat;
172 fileSize = respositoryMetadata.repoSize;
173 if (respositoryMetadata.smartCrops != null && dimension != null) {
174 smartCrops = respositoryMetadata.smartCrops.entrySet().stream()
175 .filter(entry -> isSmartCropDefinitionValid(entry.getKey(), entry.getValue()))
176 .map(entry -> new SmartCrop(entry.getKey(), entry.getValue(), dimension))
177 .collect(Collectors.toList());
178 }
179 }
180
181 return new NextGenDynamicMediaMetadata(mimeType, fileSize, dimension, assetStatus, properties, smartCrops);
182 }
183
184 private static @Nullable Dimension toDimension(long width, long height) {
185 if (width > 0 && height > 0) {
186 return new Dimension(width, height);
187 }
188 return null;
189 }
190
191 private static boolean isSmartCropDefinitionValid(@NotNull String name, @NotNull MetadataResponse.SmartCrop smartCop) {
192 return StringUtils.isNotBlank(name)
193 && smartCop.normalizedWidth > 0
194 && smartCop.normalizedHeight > 0
195 && smartCop.left >= 0
196 && smartCop.top >= 0;
197 }
198
199 }