View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   *
20   */
21  
22  package org.opencastproject.workflow.api;
23  
24  import org.apache.commons.lang3.StringUtils;
25  
26  import java.util.ArrayList;
27  import java.util.Collection;
28  import java.util.Collections;
29  import java.util.HashSet;
30  import java.util.List;
31  import java.util.Set;
32  import java.util.SortedSet;
33  import java.util.TreeSet;
34  
35  import javax.xml.bind.annotation.XmlAccessType;
36  import javax.xml.bind.annotation.XmlAccessorType;
37  import javax.xml.bind.annotation.XmlElement;
38  import javax.xml.bind.annotation.XmlElementWrapper;
39  import javax.xml.bind.annotation.XmlID;
40  import javax.xml.bind.annotation.XmlRootElement;
41  import javax.xml.bind.annotation.XmlType;
42  import javax.xml.bind.annotation.adapters.XmlAdapter;
43  
44  /**
45   * A JAXB-annotated implementation of {@link WorkflowDefinition}
46   */
47  @XmlType(name = "definition", namespace = "http://workflow.opencastproject.org")
48  @XmlRootElement(name = "definition", namespace = "http://workflow.opencastproject.org")
49  @XmlAccessorType(XmlAccessType.FIELD)
50  public class WorkflowDefinitionImpl implements WorkflowDefinition {
51  
52    /**
53     * Constructor to be used by JAXB only.
54     */
55    public WorkflowDefinitionImpl() {
56    }
57  
58    @XmlID
59    @XmlElement(name = "id")
60    private String id;
61  
62    @XmlElement(name = "title")
63    private String title;
64  
65    @XmlElement(name = "organization")
66    private String organization;
67  
68    @XmlElementWrapper(name = "tags")
69    @XmlElement(name = "tag")
70    protected SortedSet<String> tags = new TreeSet<>();
71  
72    @XmlElementWrapper(name = "roles")
73    @XmlElement(name = "role")
74    protected SortedSet<String> roles = new TreeSet<>();
75  
76    @XmlElement(name = "description")
77    private String description;
78  
79    @XmlElement(name = "displayOrder")
80    private int displayOrder = 0;
81  
82    @XmlElement(name = "configuration_panel")
83    private String configurationPanel;
84  
85    @XmlElement(name = "configuration_panel_json")
86    private String configurationPanelJson;
87  
88    @XmlElement(name = "operation")
89    @XmlElementWrapper(name = "operations")
90    private List<WorkflowOperationDefinition> operations;
91  
92    @XmlElement(name = "state-mapping")
93    @XmlElementWrapper(name = "state-mappings")
94    private Set<WorkflowStateMapping> stateMappings;
95  
96    /**
97     * {@inheritDoc}
98     *
99     * @see org.opencastproject.workflow.api.WorkflowDefinition#getId()
100    */
101   public String getId() {
102     return id;
103   }
104 
105   /**
106    * {@inheritDoc}
107    *
108    * @see org.opencastproject.workflow.api.WorkflowDefinition#setId(java.lang.String)
109    */
110   public void setId(String id) {
111     this.id = id;
112   }
113 
114   /**
115    * {@inheritDoc}
116    *
117    * @see org.opencastproject.workflow.api.WorkflowDefinition#getDescription()
118    */
119   public String getDescription() {
120     return description;
121   }
122 
123   /**
124    * {@inheritDoc}
125    *
126    * @see org.opencastproject.workflow.api.WorkflowDefinition#setDescription(java.lang.String)
127    */
128   public void setDescription(String description) {
129     this.description = description;
130   }
131 
132   /**
133    * {@inheritDoc}
134    *
135    * @see org.opencastproject.workflow.api.WorkflowDefinition#getDisplayOrder()
136    */
137   public int getDisplayOrder() {
138     return displayOrder;
139   }
140 
141   /**
142    * {@inheritDoc}
143    *
144    * @see org.opencastproject.workflow.api.WorkflowDefinition#setDisplayOrder(int)
145    */
146   public void setDisplayOrder(int displayOrder) {
147     this.displayOrder = displayOrder;
148   }
149 
150   /**
151    * Sets the configuration panel for this workflow.
152    *
153    * @param panelXML
154    *          the xml for the configuration panel
155    */
156   public void setConfigurationPanel(String panelXML) {
157     this.configurationPanel = panelXML;
158   }
159 
160   /**
161    * {@inheritDoc}
162    *
163    * @see org.opencastproject.workflow.api.WorkflowDefinition#getConfigurationPanel()
164    */
165   public String getConfigurationPanel() {
166     return this.configurationPanel;
167   }
168 
169   /**
170    * Sets the configuration panel for this workflow.
171    *
172    * @param panelJson
173    *          the json for the configuration panel
174    */
175   public void setConfigurationPanelJson(String panelJson) {
176     this.configurationPanelJson = panelJson;
177   }
178 
179   /**
180    * {@inheritDoc}
181    *
182    * @see org.opencastproject.workflow.api.WorkflowDefinition#getConfigurationPanelJson()
183    */
184   public String getConfigurationPanelJson() {
185     return this.configurationPanelJson;
186   }
187 
188   /**
189    * {@inheritDoc}
190    *
191    * @see org.opencastproject.workflow.api.WorkflowDefinition#getOperations()
192    */
193   public List<WorkflowOperationDefinition> getOperations() {
194     if (operations == null) {
195       operations = new ArrayList<>();
196     }
197     return operations;
198   }
199 
200   @Override
201   public Set<WorkflowStateMapping> getStateMappings() {
202     if (stateMappings == null) {
203       stateMappings = new HashSet<>();
204     }
205     return stateMappings;
206   }
207 
208   /**
209    * {@inheritDoc}
210    *
211    * @see org.opencastproject.workflow.api.WorkflowDefinition#get(int)
212    */
213   @Override
214   public WorkflowOperationDefinition get(int position) throws IndexOutOfBoundsException {
215     if (operations == null) {
216       operations = new ArrayList<>();
217     }
218     if (position < 0 || position >= operations.size()) {
219       throw new IndexOutOfBoundsException();
220     }
221     return operations.get(position);
222   }
223 
224   /**
225    * {@inheritDoc}
226    *
227    * @see org.opencastproject.workflow.api.WorkflowDefinition#add(
228    *      org.opencastproject.workflow.api.WorkflowOperationDefinition)
229    */
230   @Override
231   public void add(WorkflowOperationDefinition operation) {
232     if (operations == null) {
233       operations = new ArrayList<>();
234     }
235     add(operation, this.operations.size());
236   }
237 
238   /**
239    * {@inheritDoc}
240    *
241    * @see org.opencastproject.workflow.api.WorkflowDefinition#add(
242    *      org.opencastproject.workflow.api.WorkflowOperationDefinition, int)
243    */
244   @Override
245   public void add(WorkflowOperationDefinition operation, int position) {
246     if (operations == null) {
247       operations = new ArrayList<>();
248     }
249 
250     if (operation == null) {
251       throw new IllegalArgumentException("Workflow operation cannot be null");
252     }
253     if (position < 0 || position > operations.size()) {
254       throw new IndexOutOfBoundsException();
255     }
256 
257     if (position == operations.size()) {
258       operations.add(operation);
259     } else {
260       operations.add(position, operation);
261     }
262   }
263 
264   /**
265    * {@inheritDoc}
266    *
267    * @see org.opencastproject.workflow.api.WorkflowDefinition#remove(int)
268    */
269   @Override
270   public WorkflowOperationDefinition remove(int position) throws IndexOutOfBoundsException {
271     if (operations == null) {
272       operations = new ArrayList<>();
273     }
274     return operations.remove(position);
275   }
276 
277   /**
278    * @see org.opencastproject.workflow.api.WorkflowDefinition#addTag(String)
279    */
280   @Override
281   public void addTag(String tag) {
282     if (tag == null) {
283       throw new IllegalArgumentException("Tag must not be null");
284     }
285     tags.add(tag);
286   }
287 
288   /**
289    * @see org.opencastproject.workflow.api.WorkflowDefinition#removeTag(String)
290    */
291   @Override
292   public void removeTag(String tag) {
293     if (tag == null) {
294       return;
295     }
296     tags.remove(tag);
297   }
298 
299   /**
300    * @see org.opencastproject.workflow.api.WorkflowDefinition#containsTag(String)
301    */
302   @Override
303   public boolean containsTag(String tag) {
304     if (tag == null || tags == null) {
305       return false;
306     }
307     return tags.contains(tag);
308   }
309 
310   /**
311    * @see org.opencastproject.workflow.api.WorkflowDefinition#containsTag(Collection)
312    */
313   @Override
314   public boolean containsTag(Collection<String> tags) {
315     if (tags.size() == 0) {
316       return true;
317     }
318     for (String tag : tags) {
319       if (containsTag(tag)) {
320         return true;
321       }
322     }
323     return false;
324   }
325 
326   /**
327    * @see org.opencastproject.workflow.api.WorkflowDefinition#getTags()
328    */
329   @Override
330   public String[] getTags() {
331     return tags.toArray(new String[0]);
332   }
333 
334   /**
335    * @see org.opencastproject.workflow.api.WorkflowDefinition#clearTags()
336    */
337   @Override
338   public void clearTags() {
339     if (tags != null) {
340       tags.clear();
341     }
342   }
343 
344   /**
345    * Since we are posting workflow definitions as one post parameter in a multi-parameter post, we can not rely on
346    * "automatic" JAXB deserialization. We therefore need to provide a static valueOf(String) method to transform an XML
347    * string into a WorkflowDefinition.
348    *
349    * @param xmlString
350    *          The xml describing the workflow
351    * @return A {@link WorkflowDefinitionImpl} instance based on xmlString
352    * @throws Exception
353    *           If there is a problem marshalling the {@link WorkflowDefinitionImpl} from XML.
354    */
355   public static WorkflowDefinitionImpl valueOf(String xmlString) throws Exception {
356     return (WorkflowDefinitionImpl) XmlWorkflowParser.parseWorkflowDefinition(xmlString);
357   }
358 
359   @Override
360   public int compareTo(WorkflowDefinition workflowDefinition) {
361 
362     if (workflowDefinition == null) {
363       throw new NullPointerException("WorkflowDefinition for comparison can't be null");
364     }
365 
366     // nullsafe comparison where null is lesser than non-null
367     // workflows with null title probably aren't for displaying anyway
368     return StringUtils.compareIgnoreCase(this.getTitle(), workflowDefinition.getTitle());
369   }
370 
371   static class Adapter extends XmlAdapter<WorkflowDefinitionImpl, WorkflowDefinition> {
372     public WorkflowDefinitionImpl marshal(WorkflowDefinition op) {
373       return (WorkflowDefinitionImpl) op;
374     }
375 
376     public WorkflowDefinition unmarshal(WorkflowDefinitionImpl op) {
377       return op;
378     }
379   }
380 
381   /**
382    * @return the title
383    */
384   public String getTitle() {
385     return title;
386   }
387 
388   /**
389    * @param title
390    *          the title to set
391    */
392   public void setTitle(String title) {
393     this.title = title;
394   }
395 
396   @Override
397   public String getOrganization() {
398     return organization;
399   }
400 
401   @Override
402   public Collection<String> getRoles() {
403     if (roles == null) {
404       return Collections.emptySet();
405     }
406     return roles;
407   }
408 
409   /**
410    * {@inheritDoc}
411    *
412    * @see java.lang.Object#toString()
413    */
414   public String toString() {
415     if (organization != null) {
416       return "Workflow definition {" + id + "/" + organization + "}";
417     }
418     return "Workflow definition {" + id + "}";
419   }
420 
421 }