/**
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License
* at:
*
* http://opensource.org/licenses/ecl2.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
*/
package org.opencastproject.composer.api;
import org.opencastproject.util.EqualsUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlID;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
/**
* Default implementation for encoding profiles.
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "profile", namespace = "http://composer.opencastproject.org")
@XmlRootElement(name = "profile", namespace = "http://composer.opencastproject.org")
public class EncodingProfileImpl implements EncodingProfile {
/** The profile identifier */
@XmlAttribute(name = "id")
@XmlID
protected String identifier = null;
/** Format description */
@XmlElement(name = "name")
protected String name = null;
@XmlTransient
protected Object source;
/** Format type */
@XmlElement(name = "outputmediatype")
protected MediaType outputType = null;
/** Suffix
@XmlElement(name = "suffix")
protected String suffix = null;
*/
/** Mime type */
@XmlElement(name = "mimetype")
protected String mimeType = null;
/** The track type that this profile may be applied to */
@XmlElement(name = "inputmediatype")
protected MediaType applicableType = null;
/** Installation-specific properties */
@XmlElement(name = "extension")
@XmlElementWrapper(name = "extensions")
protected List<Extension> extensions = new ArrayList<Extension>();
@XmlElementWrapper(name = "suffixes")
protected HashMap<String,String> suffixes = new HashMap<String, String>();
@XmlElement(name = "jobLoad")
protected Float jobLoad = 1.0f;
/**
* Private, since the profile should be created using the static factory method.
*
* @param identifier
* the profile identifier
* @param name
* the profile name
*/
public EncodingProfileImpl(String identifier, String name, Object source) {
this.identifier = identifier;
this.name = name;
this.source = source;
}
// Needed by JAXB
public EncodingProfileImpl() {
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#getIdentifier()
*/
@Override
public String getIdentifier() {
return identifier;
}
/**
* Sets the identifier
*
* @param id
* the identifier
*/
public void setIdentifier(String id) {
identifier = id;
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#getName()
*/
@Override
public String getName() {
return name;
}
/**
* Sets the profile name
*
* @param name
* the profile name
*/
public void setName(String name) {
this.name = name;
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#getSource()
*/
@Override
public Object getSource() {
return source;
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#getOutputType()
*/
@Override
public MediaType getOutputType() {
return outputType;
}
/**
* Sets the output type.
*
* @param type
* the output type
*/
public void setOutputType(MediaType type) {
this.outputType = type;
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#getSuffix()
*/
@Override
public String getSuffix() {
if (suffixes.keySet().size() == 0) return null;
if (suffixes.containsKey("default")) {
return suffixes.get("default");
} else {
return suffixes.get(suffixes.values().toArray()[0]);
}
}
/**
* Sets the suffix for encoded file names.
*
* @param suffix
* the file suffix
*/
public void setSuffix(String suffix) {
setSuffix("default", suffix);
}
/**
* Sets the suffix for encoded file names.
*
* @param suffix
* the file suffix
*/
public void setSuffix(String tag ,String suffix) {
this.suffixes.put(tag, suffix);
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#getMimeType()
*/
@Override
public String getMimeType() {
return mimeType;
}
/**
* Sets the Mimetype.
*
* @param mimeType
* the Mimetype
*/
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#getApplicableMediaType()
*/
@Override
public MediaType getApplicableMediaType() {
return applicableType;
}
/**
* Sets the applicable type.
*
* @param applicableType
* the applicableType to set
*/
public void setApplicableType(MediaType applicableType) {
this.applicableType = applicableType;
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#isApplicableTo(org.opencastproject.composer.api.EncodingProfile.MediaType)
*/
@Override
public boolean isApplicableTo(MediaType type) {
if (type == null)
throw new IllegalArgumentException("Type must not be null");
return type.equals(applicableType);
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#getExtension(java.lang.String)
*/
@Override
public String getExtension(String key) {
return getExtensions().get(key);
}
/**
* Adds the given key-value pair to the extended configuration space of this media profile.
*
* @param key
* the property key
* @param value
* the property value
*/
public void addExtension(String key, String value) {
if (StringUtils.isBlank(key))
throw new IllegalArgumentException("Argument 'key' must not be null");
if (value == null)
throw new IllegalArgumentException("Argument 'value' must not be null");
removeExtension(key);
extensions.add(new Extension(key, value));
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#getExtensions()
*/
@Override
public Map<String, String> getExtensions() {
Map<String, String> map = new HashMap<String, String>();
for (Extension extension : extensions) {
map.put(extension.getKey(), extension.getValue());
}
return map;
}
/**
* Sets the extension properties for that profile. These properties may be intepreted by the encoder engine.
*
* @param extension
* the extension properties
*/
public void setExtensions(Map<String, String> extension) {
extensions.clear();
for (Entry<String, String> entry : extension.entrySet()) {
extensions.add(new Extension(entry));
}
}
/**
* Removes the specified property from the extended configuation space and returns either the property value or
* <code>null</code> if no property was found.
*
* @param key
* the property key
* @return the property value or <code>null</code>
*/
public String removeExtension(String key) {
int index = -1;
for (int i = 0; i < extensions.size(); i++) {
if (extensions.get(i).getKey().equals(key)) {
index = i;
break;
}
}
if (index == -1)
return null;
return extensions.remove(index).getValue();
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#hasExtensions()
*/
@Override
public boolean hasExtensions() {
return extensions != null && extensions.size() > 0;
}
/**
* {@inheritDoc}
*
* @see org.opencastproject.composer.api.EncodingProfile#getJobLoad()
*/
@Override
public float getJobLoad() {
return jobLoad;
}
/**
* Sets the job load for this encoding profile
*
* @param jobLoad the load caused by one instance of this encoding profile running
*/
public void setJobLoad(Float jobLoad) {
this.jobLoad = jobLoad;
}
/**
* {@inheritDoc}
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return identifier.hashCode();
}
/**
* {@inheritDoc}
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (obj instanceof EncodingProfile) {
EncodingProfile mf = (EncodingProfile) obj;
return identifier.equals(mf.getIdentifier());
}
return false;
}
/**
* {@inheritDoc}
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return identifier;
}
@Override
public String getSuffix(String tag) {
if (suffixes.containsKey(tag)) return suffixes.get(tag);
else return null;
}
@Override
public List<String> getTags() {
return new ArrayList<String>(suffixes.keySet());
}
/**
* An extension property. To read about why this class is necessary, see http://java.net/jira/browse/JAXB-223
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "extension", namespace = "http://composer.opencastproject.org")
public static class Extension {
/** The property key */
@XmlAttribute
private String key;
/** The property value */
@XmlValue
private String value;
/**
* No-arg constructor needed by JAXB
*/
public Extension() {
}
/**
* Constructs an extension property with a key and a value.
*
* @param key
* the key
* @param value
* the value
*/
public Extension(String key, String value) {
this.key = key;
this.value = value;
}
/**
* Constructs an extension property with a map entry.
*
* @param e
* the value
*/
public Extension(Map.Entry<String, String> e) {
key = e.getKey();
value = e.getValue();
}
/**
* @return the key
*/
public String getKey() {
return key;
}
/**
* @return the value
*/
public String getValue() {
return value;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Extension) {
Extension ext = (Extension) obj;
return key.equals(ext.getKey()) && value.equals(ext.getValue());
}
return false;
}
@Override
public int hashCode() {
return EqualsUtil.hash(key, value);
}
}
}