1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.opencastproject.message.broker.api.assetmanager;
22
23 import static com.entwinemedia.fn.Prelude.chuck;
24
25 import org.opencastproject.mediapackage.Catalog;
26 import org.opencastproject.mediapackage.MediaPackage;
27 import org.opencastproject.mediapackage.MediaPackageElements;
28 import org.opencastproject.mediapackage.MediaPackageException;
29 import org.opencastproject.mediapackage.MediaPackageParser;
30 import org.opencastproject.message.broker.api.MessageItem;
31 import org.opencastproject.metadata.dublincore.DublinCoreCatalog;
32 import org.opencastproject.metadata.dublincore.DublinCores;
33 import org.opencastproject.security.api.AccessControlList;
34 import org.opencastproject.security.api.AccessControlParser;
35 import org.opencastproject.util.RequireUtil;
36 import org.opencastproject.workspace.api.Workspace;
37
38 import com.entwinemedia.fn.Fn;
39 import com.entwinemedia.fn.data.Opt;
40
41 import org.apache.commons.io.IOUtils;
42
43 import java.io.IOException;
44 import java.io.InputStream;
45 import java.io.Serializable;
46 import java.nio.charset.StandardCharsets;
47 import java.util.Date;
48
49 import javax.annotation.ParametersAreNonnullByDefault;
50
51
52
53
54 @ParametersAreNonnullByDefault
55 public abstract class AssetManagerItem implements MessageItem, Serializable {
56 private static final long serialVersionUID = 5440420510139202434L;
57
58 public enum Type {
59 Update, Delete
60 }
61
62
63
64 private final String mediaPackageId;
65 private final long date;
66
67 private AssetManagerItem(String mediaPackageId, Date date) {
68 this.mediaPackageId = RequireUtil.notNull(mediaPackageId, "mediaPackageId");
69 this.date = RequireUtil.notNull(date, "date").getTime();
70 }
71
72 public abstract Type getType();
73
74 public abstract <A> A decompose(Fn<? super TakeSnapshot, ? extends A> takeSnapshot,
75 Fn<? super DeleteEpisode, ? extends A> deleteEpisode);
76
77 public final Date getDate() {
78 return new Date(date);
79 }
80
81 @Override
82 public final String getId() {
83 return mediaPackageId;
84 }
85
86
87
88
89
90
91
92
93 public static final class TakeSnapshot extends AssetManagerItem {
94 private static final long serialVersionUID = 3530625835200867594L;
95
96 private final String mediapackage;
97 private final String acl;
98 private final long version;
99 private final String episodeDublincore;
100
101 private TakeSnapshot(String mediaPackageId, String mediapackage, String episodeDublincore, String acl, long version,
102 Date date) {
103 super(mediaPackageId, date);
104 this.mediapackage = mediapackage;
105 this.episodeDublincore = episodeDublincore;
106 this.acl = acl;
107 this.version = version;
108 }
109
110 @Override
111 public <A> A decompose(Fn<? super TakeSnapshot, ? extends A> takeSnapshot,
112 Fn<? super DeleteEpisode, ? extends A> deleteEpisode) {
113 return takeSnapshot.apply(this);
114 }
115
116 @Override
117 public Type getType() {
118 return Type.Update;
119 }
120
121 public MediaPackage getMediapackage() {
122 try {
123 return MediaPackageParser.getFromXml(mediapackage);
124 } catch (MediaPackageException e) {
125 return chuck(e);
126 }
127 }
128
129 public AccessControlList getAcl() {
130 return AccessControlParser.parseAclSilent(acl);
131 }
132
133 public Opt<DublinCoreCatalog> getEpisodeDublincore() {
134 if (episodeDublincore == null) {
135 return Opt.none();
136 }
137
138 try (InputStream is = IOUtils.toInputStream(episodeDublincore, "UTF-8")) {
139 return Opt.some(DublinCores.read(is));
140 } catch (IOException e) {
141 return chuck(e);
142 }
143 }
144
145 public long getVersion() {
146 return version;
147 }
148
149
150
151 public static final Fn<TakeSnapshot, MediaPackage> getMediaPackage = new Fn<TakeSnapshot, MediaPackage>() {
152 @Override
153 public MediaPackage apply(TakeSnapshot a) {
154 return a.getMediapackage();
155 }
156 };
157
158 public static final Fn<TakeSnapshot, Opt<DublinCoreCatalog>> getEpisodeDublincore
159 = new Fn<TakeSnapshot, Opt<DublinCoreCatalog>>() {
160 @Override
161 public Opt<DublinCoreCatalog> apply(TakeSnapshot a) {
162 return a.getEpisodeDublincore();
163 }
164 };
165
166 public static final Fn<TakeSnapshot, AccessControlList> getAcl = new Fn<TakeSnapshot, AccessControlList>() {
167 @Override
168 public AccessControlList apply(TakeSnapshot a) {
169 return a.getAcl();
170 }
171 };
172
173 }
174
175
176
177
178
179
180
181
182
183
184
185
186 public static final class DeleteEpisode extends AssetManagerItem {
187 private static final long serialVersionUID = -4906056424740181256L;
188
189 private DeleteEpisode(String mediaPackageId, Date date) {
190 super(mediaPackageId, date);
191 }
192
193 @Override
194 public <A> A decompose(Fn<? super TakeSnapshot, ? extends A> takeSnapshot,
195 Fn<? super DeleteEpisode, ? extends A> deleteEpisode) {
196 return deleteEpisode.apply(this);
197 }
198
199 @Override
200 public Type getType() {
201 return Type.Delete;
202 }
203
204 public String getMediaPackageId() {
205 return getId();
206 }
207
208 public static final Fn<DeleteEpisode, String> getMediaPackageId = new Fn<DeleteEpisode, String>() {
209 @Override
210 public String apply(DeleteEpisode a) {
211 return a.getMediaPackageId();
212 }
213 };
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237 public static TakeSnapshot add(Workspace workspace, MediaPackage mp, AccessControlList acl, long version, Date date) {
238 String dcXml = null;
239 for (Catalog catalog: mp.getCatalogs(MediaPackageElements.EPISODE)) {
240 try (InputStream in = workspace.read(catalog.getURI())) {
241 dcXml = IOUtils.toString(in, StandardCharsets.UTF_8);
242 } catch (Exception e) {
243 throw new IllegalStateException(String.format("Unable to load dublin core catalog for event '%s'",
244 mp.getIdentifier()), e);
245 }
246 }
247 return new TakeSnapshot(mp.getIdentifier().toString(), MediaPackageParser.getAsXml(mp), dcXml,
248 AccessControlParser.toJsonSilent(acl), version, date);
249 }
250
251
252
253
254
255
256
257
258 public static AssetManagerItem deleteEpisode(String mediaPackageId, Date date) {
259 return new DeleteEpisode(mediaPackageId, date);
260 }
261 }