1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.rest.reference.dam;
35
36 import info.magnolia.cms.util.DateUtil;
37 import info.magnolia.dam.api.Asset;
38 import info.magnolia.dam.api.metadata.DublinCore;
39 import info.magnolia.dam.api.metadata.MagnoliaAssetMetadata;
40
41 import java.io.IOException;
42 import java.io.OutputStream;
43 import java.lang.annotation.Annotation;
44 import java.lang.reflect.Type;
45 import java.nio.charset.Charset;
46 import java.util.Arrays;
47
48 import javax.json.Json;
49 import javax.json.stream.JsonGenerator;
50 import javax.ws.rs.Produces;
51 import javax.ws.rs.WebApplicationException;
52 import javax.ws.rs.core.MediaType;
53 import javax.ws.rs.core.MultivaluedMap;
54 import javax.ws.rs.ext.MessageBodyWriter;
55 import javax.ws.rs.ext.Provider;
56
57 import org.apache.commons.collections4.CollectionUtils;
58 import org.apache.commons.lang3.ArrayUtils;
59 import org.apache.commons.lang3.StringUtils;
60
61
62
63
64 @Provider
65 @Produces({ MediaType.APPLICATION_JSON })
66 public class AssetWriter implements MessageBodyWriter<Asset> {
67
68 private static final String DATE_TIME_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
69
70 @Override
71 public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
72 return Asset.class.isAssignableFrom(type);
73 }
74
75 @Override
76 public long getSize(Asset asset, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
77
78 return -1;
79 }
80
81 @Override
82 public void writeTo(Asset asset, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
83 boolean includeAssetLinkOnly = (asset instanceof ConfigurableAssetWrapper) && !((ConfigurableAssetWrapper) asset).isExpand() && ((ConfigurableAssetWrapper) asset).isIncludeDownloadLink();
84 if (includeAssetLinkOnly) {
85 String downloadLink = String.format("\"%s\"", asset.getLink());
86 entityStream.write(downloadLink.getBytes(Charset.forName("UTF-8")));
87 return;
88 }
89
90 JsonGenerator jsonGenerator = Json.createGenerator(entityStream);
91 jsonGenerator.writeStartObject();
92 jsonGenerator.write("@name", asset.getName());
93 jsonGenerator.write("@path", asset.getPath());
94 jsonGenerator.write("@id", asset.getItemKey().asString());
95
96 try {
97 Class jcrProvider = Class.forName("info.magnolia.dam.jcr.JcrAssetProvider");
98 if (asset.getAssetProvider().getClass().isInstance(jcrProvider)) {
99 jsonGenerator.write("@nodeType", "mgnl:asset");
100 }
101 } catch (ClassNotFoundException e) {
102
103 }
104
105 if (!(asset instanceof ConfigurableAssetWrapper) || ((ConfigurableAssetWrapper) asset).isIncludeDownloadLink()) {
106 jsonGenerator.write("@link", asset.getLink());
107 }
108
109 if (!(asset instanceof ConfigurableAssetWrapper) || ((ConfigurableAssetWrapper) asset).isIncludeAssetMetadata()) {
110 jsonGenerator.writeStartObject("metadata");
111 writeNonEmptyKeyValue(jsonGenerator, "fileName", asset.getFileName());
112 writeNonEmptyKeyValue(jsonGenerator, "mimeType", asset.getMimeType());
113 writeNonEmptyKeyValue(jsonGenerator, "caption", asset.getCaption());
114 writeNonEmptyKeyValue(jsonGenerator, "comment", asset.getComment());
115 writeNonEmptyKeyValue(jsonGenerator, "fileSize", String.valueOf(asset.getFileSize()));
116
117 if (asset.supports(MagnoliaAssetMetadata.class)) {
118 MagnoliaAssetMetadata metadata = asset.getMetadata(MagnoliaAssetMetadata.class);
119 writeNonEmptyKeyValue(jsonGenerator, "height", String.valueOf(metadata.getHeight()));
120 writeNonEmptyKeyValue(jsonGenerator, "width", String.valueOf(metadata.getWidth()));
121 }
122
123
124 if (asset.supports(DublinCore.class)) {
125 DublinCore metadata = asset.getMetadata(DublinCore.class);
126 writeNonEmptyKeyValue(jsonGenerator, "type", metadata.getType());
127 writeNonEmptyKeyValue(jsonGenerator, "title", metadata.getTitle());
128 writeNonEmptyKeyValue(jsonGenerator, "format", metadata.getFormat());
129 writeNonEmptyKeyValue(jsonGenerator, "coverage", metadata.getCoverage());
130 writeNonEmptyKeyValue(jsonGenerator, "description", metadata.getDescription());
131 writeNonEmptyKeyValue(jsonGenerator, "language", asset.getLanguage());
132 writeNonEmptyKeyValue(jsonGenerator, "publisher", metadata.getPublisher());
133 writeNonEmptyKeyValue(jsonGenerator, "relation", metadata.getRelation());
134 writeNonEmptyKeyValue(jsonGenerator, "rights", metadata.getRights());
135 writeNonEmptyKeyValue(jsonGenerator, "source", metadata.getSource());
136 writeNonEmptyStringArray(jsonGenerator, "creator", metadata.getCreator());
137 writeNonEmptyStringArray(jsonGenerator, "contributor", metadata.getContributor());
138 writeNonEmptyStringArray(jsonGenerator, "subject", metadata.getSubject());
139 writeNonEmptyKeyValue(jsonGenerator, "date", DateUtil.format(metadata.getDate().getTime(), DATE_TIME_PATTERN));
140 writeNonEmptyKeyValue(jsonGenerator, "created", DateUtil.format(asset.getCreated().getTime(), DATE_TIME_PATTERN));
141 writeNonEmptyKeyValue(jsonGenerator, "modified", DateUtil.format(asset.getLastModified().getTime(), DATE_TIME_PATTERN));
142 }
143 jsonGenerator.writeEnd();
144 }
145
146 if ((asset instanceof ConfigurableAssetWrapper) && CollectionUtils.isNotEmpty(((ConfigurableAssetWrapper) asset).getAssetRenditions())) {
147 jsonGenerator.writeStartObject("renditions");
148 ((ConfigurableAssetWrapper) asset).getAssetRenditions().forEach(rendition -> {
149 jsonGenerator.writeStartObject(rendition.getRenditionName());
150 jsonGenerator.write("mimeType", rendition.getMimeType());
151 jsonGenerator.write("link", rendition.getLink());
152 jsonGenerator.writeEnd();
153 });
154 jsonGenerator.writeEnd();
155 }
156 jsonGenerator.writeEnd();
157 jsonGenerator.flush();
158 }
159
160 private void writeNonEmptyKeyValue(JsonGenerator jsonGenerator, String key, String value) {
161 if (StringUtils.isNotEmpty(value)) {
162 jsonGenerator.write(key, value);
163 }
164 }
165
166 private void writeNonEmptyStringArray(JsonGenerator jsonGenerator, String key, String[] values) {
167 String[] nonEmptyValues = Arrays.stream(ArrayUtils.nullToEmpty(values))
168 .filter(StringUtils::isNotEmpty)
169 .toArray(String[]::new);
170 if (ArrayUtils.isEmpty(nonEmptyValues)) {
171 return;
172 }
173 jsonGenerator.writeStartArray(key);
174 for (String value : nonEmptyValues) {
175 jsonGenerator.write(value);
176 }
177 jsonGenerator.writeEnd();
178 }
179 }