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     return operations;
197   }
198 
199   @Override
200   public Set<WorkflowStateMapping> getStateMappings() {
201     if (stateMappings == null) {
202       stateMappings = new HashSet<>();
203     }
204     return stateMappings;
205   }
206 
207   /**
208    * {@inheritDoc}
209    *
210    * @see org.opencastproject.workflow.api.WorkflowDefinition#get(int)
211    */
212   @Override
213   public WorkflowOperationDefinition get(int position) throws IndexOutOfBoundsException {
214     if (operations == null)
215       operations = new ArrayList<>();
216     if (position < 0 || position >= operations.size())
217       throw new IndexOutOfBoundsException();
218     return operations.get(position);
219   }
220 
221   /**
222    * {@inheritDoc}
223    *
224    * @see org.opencastproject.workflow.api.WorkflowDefinition#add(org.opencastproject.workflow.api.WorkflowOperationDefinition)
225    */
226   @Override
227   public void add(WorkflowOperationDefinition operation) {
228     if (operations == null)
229       operations = new ArrayList<>();
230     add(operation, this.operations.size());
231   }
232 
233   /**
234    * {@inheritDoc}
235    *
236    * @see org.opencastproject.workflow.api.WorkflowDefinition#add(org.opencastproject.workflow.api.WorkflowOperationDefinition,
237    *      int)
238    */
239   @Override
240   public void add(WorkflowOperationDefinition operation, int position) {
241     if (operations == null)
242       operations = new ArrayList<>();
243 
244     if (operation == null)
245       throw new IllegalArgumentException("Workflow operation cannot be null");
246     if (position < 0 || position > operations.size())
247       throw new IndexOutOfBoundsException();
248 
249     if (position == operations.size())
250       operations.add(operation);
251     else
252       operations.add(position, operation);
253   }
254 
255   /**
256    * {@inheritDoc}
257    *
258    * @see org.opencastproject.workflow.api.WorkflowDefinition#remove(int)
259    */
260   @Override
261   public WorkflowOperationDefinition remove(int position) throws IndexOutOfBoundsException {
262     if (operations == null)
263       operations = new ArrayList<>();
264     return operations.remove(position);
265   }
266 
267   /**
268    * @see org.opencastproject.workflow.api.WorkflowDefinition#addTag(String)
269    */
270   @Override
271   public void addTag(String tag) {
272     if (tag == null)
273       throw new IllegalArgumentException("Tag must not be null");
274     tags.add(tag);
275   }
276 
277   /**
278    * @see org.opencastproject.workflow.api.WorkflowDefinition#removeTag(String)
279    */
280   @Override
281   public void removeTag(String tag) {
282     if (tag == null)
283       return;
284     tags.remove(tag);
285   }
286 
287   /**
288    * @see org.opencastproject.workflow.api.WorkflowDefinition#containsTag(String)
289    */
290   @Override
291   public boolean containsTag(String tag) {
292     if (tag == null || tags == null)
293       return false;
294     return tags.contains(tag);
295   }
296 
297   /**
298    * @see org.opencastproject.workflow.api.WorkflowDefinition#containsTag(Collection)
299    */
300   @Override
301   public boolean containsTag(Collection<String> tags) {
302     if (tags.size() == 0)
303       return true;
304     for (String tag : tags) {
305       if (containsTag(tag))
306         return true;
307     }
308     return false;
309   }
310 
311   /**
312    * @see org.opencastproject.workflow.api.WorkflowDefinition#getTags()
313    */
314   @Override
315   public String[] getTags() {
316     return tags.toArray(new String[0]);
317   }
318 
319   /**
320    * @see org.opencastproject.workflow.api.WorkflowDefinition#clearTags()
321    */
322   @Override
323   public void clearTags() {
324     if (tags != null)
325       tags.clear();
326   }
327 
328   /**
329    * Since we are posting workflow definitions as one post parameter in a multi-parameter post, we can not rely on
330    * "automatic" JAXB deserialization. We therefore need to provide a static valueOf(String) method to transform an XML
331    * string into a WorkflowDefinition.
332    *
333    * @param xmlString
334    *          The xml describing the workflow
335    * @return A {@link WorkflowDefinitionImpl} instance based on xmlString
336    * @throws Exception
337    *           If there is a problem marshalling the {@link WorkflowDefinitionImpl} from XML.
338    */
339   public static WorkflowDefinitionImpl valueOf(String xmlString) throws Exception {
340     return (WorkflowDefinitionImpl) XmlWorkflowParser.parseWorkflowDefinition(xmlString);
341   }
342 
343   @Override
344   public int compareTo(WorkflowDefinition workflowDefinition) {
345 
346     if (workflowDefinition == null) {
347       throw new NullPointerException("WorkflowDefinition for comparison can't be null");
348     }
349 
350     // nullsafe comparison where null is lesser than non-null
351     // workflows with null title probably aren't for displaying anyway
352     return StringUtils.compareIgnoreCase(this.getTitle(), workflowDefinition.getTitle());
353   }
354 
355   static class Adapter extends XmlAdapter<WorkflowDefinitionImpl, WorkflowDefinition> {
356     public WorkflowDefinitionImpl marshal(WorkflowDefinition op) {
357       return (WorkflowDefinitionImpl) op;
358     }
359 
360     public WorkflowDefinition unmarshal(WorkflowDefinitionImpl op) {
361       return op;
362     }
363   }
364 
365   /**
366    * @return the title
367    */
368   public String getTitle() {
369     return title;
370   }
371 
372   /**
373    * @param title
374    *          the title to set
375    */
376   public void setTitle(String title) {
377     this.title = title;
378   }
379 
380   @Override
381   public String getOrganization() {
382     return organization;
383   }
384 
385   @Override
386   public Collection<String> getRoles() {
387     if (roles == null) {
388       return Collections.emptySet();
389     }
390     return roles;
391   }
392 
393   /**
394    * {@inheritDoc}
395    *
396    * @see java.lang.Object#toString()
397    */
398   public String toString() {
399     if (organization != null) {
400       return "Workflow definition {" + id + "/" + organization + "}";
401     }
402     return "Workflow definition {" + id + "}";
403   }
404 
405 }