1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.workflow.handler.workflow;
23
24 import static java.lang.String.format;
25
26 import org.opencastproject.job.api.JobContext;
27 import org.opencastproject.mediapackage.MediaPackage;
28 import org.opencastproject.mediapackage.MediaPackageElement;
29 import org.opencastproject.mediapackage.MediaPackageElementFlavor;
30 import org.opencastproject.mediapackage.selector.AbstractMediaPackageElementSelector;
31 import org.opencastproject.mediapackage.selector.SimpleElementSelector;
32 import org.opencastproject.serviceregistry.api.ServiceRegistry;
33 import org.opencastproject.util.FileSupport;
34 import org.opencastproject.util.NotFoundException;
35 import org.opencastproject.util.UrlSupport;
36 import org.opencastproject.util.data.Option;
37 import org.opencastproject.workflow.api.AbstractWorkflowOperationHandler;
38 import org.opencastproject.workflow.api.ConfiguredTagsAndFlavors;
39 import org.opencastproject.workflow.api.WorkflowInstance;
40 import org.opencastproject.workflow.api.WorkflowOperationException;
41 import org.opencastproject.workflow.api.WorkflowOperationHandler;
42 import org.opencastproject.workflow.api.WorkflowOperationInstance;
43 import org.opencastproject.workflow.api.WorkflowOperationResult;
44 import org.opencastproject.workflow.api.WorkflowOperationResult.Action;
45 import org.opencastproject.workspace.api.Workspace;
46
47 import org.apache.commons.io.FilenameUtils;
48 import org.apache.commons.lang3.StringUtils;
49 import org.osgi.service.component.annotations.Component;
50 import org.osgi.service.component.annotations.Reference;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 import java.io.File;
55 import java.io.IOException;
56 import java.util.Collection;
57 import java.util.List;
58
59
60
61
62 @Component(
63 immediate = true,
64 service = WorkflowOperationHandler.class,
65 property = {
66 "service.description=Copy Workflow Operation Handler",
67 "workflow.operation=copy"
68 }
69 )
70 public class CopyWorkflowOperationHandler extends AbstractWorkflowOperationHandler {
71
72 public static final String OPT_SOURCE_TAGS = "source-tags";
73
74
75 public static final String OPT_SOURCE_FLAVORS = "source-flavors";
76
77
78 public static final String OPT_TARGET_DIRECTORY = "target-directory";
79
80
81 public static final String OPT_TARGET_FILENAME = "target-filename";
82
83
84 private static final Logger logger = LoggerFactory.getLogger(CopyWorkflowOperationHandler.class);
85
86
87 protected Workspace workspace = null;
88
89
90
91
92
93
94
95 @Reference
96 protected void setWorkspace(Workspace workspace) {
97 this.workspace = workspace;
98 }
99
100
101
102
103 @Override
104 public WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context)
105 throws WorkflowOperationException {
106 logger.debug("Running copy workflow operation on workflow {}", workflowInstance.getId());
107
108 MediaPackage mediaPackage = workflowInstance.getMediaPackage();
109 WorkflowOperationInstance currentOperation = workflowInstance.getCurrentOperation();
110
111
112 ConfiguredTagsAndFlavors tagsAndFlavors = getTagsAndFlavors(workflowInstance,
113 Configuration.many, Configuration.many, Configuration.none, Configuration.none);
114 List<String> sourceTagsOption = tagsAndFlavors.getSrcTags();
115 List<MediaPackageElementFlavor> sourceFlavorsOption = tagsAndFlavors.getSrcFlavors();
116 String targetDirectoryOption = StringUtils.trimToNull(currentOperation.getConfiguration(OPT_TARGET_DIRECTORY));
117 Option<String> targetFilenameOption = Option.option(StringUtils.trimToNull(currentOperation
118 .getConfiguration(OPT_TARGET_FILENAME)));
119
120 StringBuilder sb = new StringBuilder();
121 sb.append("Parameters passed to copy workflow operation:");
122 sb.append("\n source-tags: ").append(sourceTagsOption);
123 sb.append("\n source-flavors: ").append(sourceFlavorsOption);
124 sb.append("\n target-directory: ").append(targetDirectoryOption);
125 sb.append("\n target-filename: ").append(targetFilenameOption);
126 logger.debug(sb.toString());
127
128 AbstractMediaPackageElementSelector<MediaPackageElement> elementSelector = new SimpleElementSelector();
129
130
131 if (sourceTagsOption.isEmpty() && sourceFlavorsOption.isEmpty()) {
132 logger.info("No source tags or flavors have been specified, not matching anything");
133 return createResult(mediaPackage, Action.CONTINUE);
134 }
135
136
137 if (StringUtils.isBlank(targetDirectoryOption)) {
138 throw new WorkflowOperationException("No target directory has been set for the copy operation!");
139 }
140
141
142 for (MediaPackageElementFlavor flavor : sourceFlavorsOption) {
143 try {
144 elementSelector.addFlavor(flavor);
145 } catch (IllegalArgumentException e) {
146 throw new WorkflowOperationException("Source flavor '" + flavor + "' is malformed");
147 }
148 }
149
150
151 for (String tag : sourceTagsOption) {
152 elementSelector.addTag(tag);
153 }
154
155
156 Collection<MediaPackageElement> elements = elementSelector.select(mediaPackage, true);
157
158
159 if (elements.size() == 0) {
160
161 return createResult(mediaPackage, Action.SKIP);
162 } else if (elements.size() == 1) {
163 for (MediaPackageElement element : elements) {
164 logger.debug("Copy single element to: {}", targetDirectoryOption);
165 final String fileName;
166 if (targetFilenameOption.isSome()) {
167 fileName = targetFilenameOption.get();
168 } else {
169 fileName = FilenameUtils.getBaseName(element.getURI().toString());
170 }
171
172 String ext = FilenameUtils.getExtension(element.getURI().toString());
173 ext = ext.length() > 0 ? ".".concat(ext) : "";
174 File targetFile = new File(UrlSupport.concat(targetDirectoryOption, fileName.concat(ext)));
175
176 copyElement(element, targetFile);
177 }
178 } else {
179 logger.debug("Copy multiple elements to: {}", targetDirectoryOption);
180 int i = 1;
181 for (MediaPackageElement element : elements) {
182 final String fileName;
183 if (targetFilenameOption.isSome()) {
184 fileName = String.format(targetFilenameOption.get(), i);
185 } else {
186 fileName = FilenameUtils.getBaseName(element.getURI().toString());
187 }
188
189 String ext = FilenameUtils.getExtension(element.getURI().toString());
190 ext = ext.length() > 0 ? ".".concat(ext) : "";
191 File targetFile = new File(UrlSupport.concat(targetDirectoryOption, fileName + ext));
192
193 copyElement(element, targetFile);
194 i++;
195 }
196 }
197
198 return createResult(mediaPackage, Action.CONTINUE);
199 }
200
201 private void copyElement(MediaPackageElement element, File targetFile) throws WorkflowOperationException {
202 File sourceFile;
203 try {
204 sourceFile = workspace.get(element.getURI());
205 } catch (NotFoundException e) {
206 throw new WorkflowOperationException("Unable to find " + element.getURI() + " in the workspace", e);
207 } catch (IOException e) {
208 throw new WorkflowOperationException("Error loading " + element.getURI() + " from the workspace", e);
209 }
210
211 logger.debug("Start copying element {} to target {}.", sourceFile.getPath(), targetFile.getPath());
212 try {
213 FileSupport.copy(sourceFile, targetFile);
214 } catch (IOException e) {
215 throw new WorkflowOperationException(format("Unable to copy %s to %s: %s", sourceFile.getPath(),
216 targetFile.getPath(), e.getMessage()));
217 }
218 logger.debug("Element {} copied to target {}.", sourceFile.getPath(), targetFile.getPath());
219 }
220
221 @Reference
222 @Override
223 public void setServiceRegistry(ServiceRegistry serviceRegistry) {
224 super.setServiceRegistry(serviceRegistry);
225 }
226
227 }