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.dam.imaging;
35
36 import static com.google.common.net.MediaType.*;
37
38 import info.magnolia.context.MgnlContext;
39 import info.magnolia.dam.api.Asset;
40 import info.magnolia.dam.api.AssetDecorator;
41 import info.magnolia.dam.api.AssetRenderer;
42 import info.magnolia.dam.api.AssetRendition;
43 import info.magnolia.dam.api.DamException;
44 import info.magnolia.dam.jcr.AssetNodeTypes;
45 import info.magnolia.dam.jcr.DamConstants;
46 import info.magnolia.dam.jcr.JcrAsset;
47 import info.magnolia.imaging.ImagingSupport;
48 import info.magnolia.module.site.Site;
49 import info.magnolia.module.site.functions.SiteFunctions;
50
51 import java.io.InputStream;
52 import java.util.Arrays;
53 import java.util.List;
54
55 import javax.inject.Inject;
56 import javax.inject.Provider;
57 import javax.jcr.Node;
58 import javax.jcr.Property;
59 import javax.jcr.RepositoryException;
60
61 import org.apache.jackrabbit.JcrConstants;
62
63 import com.google.common.net.MediaType;
64
65
66
67
68
69
70 public class ImagingBasedAssetRenderer implements AssetRenderer {
71
72 private final ImagingSupport imagingSupport;
73 private final Provider<Site> siteProvider;
74 private final SiteFunctions siteFunctions;
75
76
77
78
79 private final List<MediaType> mediaTypes = Arrays.asList(BMP, JPEG, GIF, TIFF, PNG);
80
81
82
83
84 private final List<MediaType> outputMediaTypes = Arrays.asList(JPEG, GIF, PNG);
85
86 @Inject
87 public ImagingBasedAssetRenderer(Provider<Site> siteProvider, SiteFunctions siteFunctions, ImagingSupport imagingSupport) {
88 this.siteProvider = siteProvider;
89 this.siteFunctions = siteFunctions;
90 this.imagingSupport = imagingSupport;
91 }
92
93
94
95
96
97 @Override
98 public boolean supports(MediaType from, MediaType to) {
99 if (from == null || to == null) {
100 return false;
101 }
102 return mediaTypes.contains(from) && outputMediaTypes.contains(to);
103 }
104
105
106
107
108
109
110
111 @Override
112 public boolean canRender(Asset asset, MediaType to) {
113 final Asset unwrappedAsset = unwrapDecoratedAsset(asset);
114 if (unwrappedAsset == null || !(unwrappedAsset instanceof JcrAsset)) {
115 return false;
116 }
117 return supports(MediaType.parse(unwrappedAsset.getMimeType()), to);
118 }
119
120
121
122
123 @Override
124 public AssetRendition render(Asset asset, MediaType to, String renditionName) {
125 final Site site = siteProvider.get();
126
127 final ImagingSupport imagingSupport;
128 if (site == null) {
129 imagingSupport = this.imagingSupport;
130 } else {
131 imagingSupport = siteFunctions.theme(site).getImaging();
132 }
133
134 asset = unwrapDecoratedAsset(asset);
135
136 if (asset instanceof JcrAsset) {
137 try {
138 final Property jcrDataProperty = getBinaryProperty((JcrAsset) asset);
139 final String link = imagingSupport.createLink(jcrDataProperty, renditionName);
140
141 return new ImagingBasedAssetRendition(asset, link, to, renditionName);
142 } catch (RepositoryException e) {
143 throw new AssetRenditionException(String.format("Asset rendition '%s' could not be generated.", renditionName), e);
144 }
145 } else {
146 throw new AssetRenditionException("Asset renditions of non-jcr assets cannot be generated.", new IllegalArgumentException());
147 }
148 }
149
150
151
152
153 private Property getBinaryProperty(JcrAsset jcrAsset) throws RepositoryException {
154 final String assetId = jcrAsset.getItemKey().getAssetId();
155 final Node assetNode = MgnlContext.getJCRSession(DamConstants.WORKSPACE).getNodeByIdentifier(assetId);
156 final Node resourceNode = AssetNodeTypes.AssetResource.getResourceNodeFromAsset(assetNode);
157 return resourceNode.getProperty(JcrConstants.JCR_DATA);
158 }
159
160
161
162
163
164
165
166 private Asset unwrapDecoratedAsset(Asset asset) {
167 if (asset instanceof AssetDecorator) {
168 return AssetDecorator.unwrap(asset);
169 }
170 return asset;
171 }
172
173
174
175
176 private static class ImagingBasedAssetRendition implements AssetRendition {
177
178 private final Asset asset;
179 private final String link;
180 private final String renditionName;
181 private final MediaType mimeType;
182
183 public ImagingBasedAssetRendition(Asset asset, String link, MediaType mediaType, String renditionName) {
184 this.asset = asset;
185 this.link = link;
186 this.renditionName = renditionName;
187 this.mimeType = mediaType;
188 }
189
190 @Override
191 public String getRenditionName() {
192 return renditionName;
193 }
194
195 @Override
196 public String getMimeType() {
197 return mimeType.toString();
198 }
199
200
201
202
203
204 @Override
205 public InputStream getStream() {
206 throw new UnsupportedOperationException();
207 }
208
209 @Override
210 public Asset getAsset() {
211 return asset;
212 }
213
214 @Override
215 public String getLink() {
216 return link;
217 }
218
219 }
220
221
222
223
224
225 protected static class AssetRenditionException extends DamException {
226 public AssetRenditionException(String message, Throwable throwable) {
227 super(message, throwable);
228 }
229 }
230
231 }