org.opencastproject.mediapackage.selector.AbstractMediaPackageElementSelector Maven / Gradle / Ivy
/*
* 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.mediapackage.selector;
import org.opencastproject.mediapackage.MediaPackage;
import org.opencastproject.mediapackage.MediaPackageElement;
import org.opencastproject.mediapackage.MediaPackageElementFlavor;
import org.opencastproject.mediapackage.MediaPackageElementSelector;
import org.opencastproject.mediapackage.Publication;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
/**
* This selector will return any MediaPackageElement
s from a MediaPackage
that matches the tag
* and flavors.
*/
public abstract class AbstractMediaPackageElementSelector implements
MediaPackageElementSelector {
/** The tags */
protected Set tags = new HashSet();
/** The tags to exclude */
protected Set excludeTags = new HashSet();
/** The flavors */
protected List flavors = new ArrayList();
/**
* The prefix indicating that a tag should be excluded from a search for elements using
* {@link MediaPackage#getElementsByTags(Collection)}
*/
public static final String NEGATE_TAG_PREFIX = "-";
/**
* This base implementation will return those media package elements that match the type specified as the type
* parameter to the class and that flavor (if specified) AND at least one of the tags (if specified) match.
*/
@Override
public Collection select(MediaPackage mediaPackage, boolean withTagsAndFlavors) {
return select(Arrays.asList(mediaPackage.getElements()), withTagsAndFlavors);
}
/**
* Similar to above, but will get media package elements from the given publication instead.
*/
@Override
public Collection select(MediaPackage mediaPackage, String publicationChannel, boolean withTagsAndFlavors) {
Optional publication = Arrays.stream(mediaPackage.getPublications())
.filter(channel -> channel.getChannel().equals(publicationChannel)).findFirst();
// Skip if the media package does not contain a matching publication
if (publication.isEmpty()) {
return new LinkedHashSet();
}
List list = new ArrayList(Arrays.asList(publication.get().getTracks()));
list.addAll(new ArrayList(Arrays.asList(publication.get().getAttachments())));
list.addAll(new ArrayList(Arrays.asList(publication.get().getCatalogs())));
return select(list, withTagsAndFlavors);
}
@Override
@SuppressWarnings("unchecked")
public Collection select(List elements, boolean withTagsAndFlavors) {
Set result = new LinkedHashSet();
// If no flavors and tags are set, return empty list
if (flavors.isEmpty() && tags.isEmpty())
return result;
Class type = getParametrizedType(result);
elementLoop: for (MediaPackageElement e : elements) {
// Does the type match?
if (type.isAssignableFrom(e.getClass())) {
for (String tag : e.getTags()) {
if (excludeTags.contains(tag))
continue elementLoop;
}
// Any of the flavors?
boolean matchesFlavor = false;
for (MediaPackageElementFlavor flavor : flavors) {
if (flavor.matches(e.getFlavor())) {
matchesFlavor = true;
break;
}
}
if (flavors.isEmpty())
matchesFlavor = true;
// If the elements selection is done by tags AND flavors
if (withTagsAndFlavors && matchesFlavor && e.containsTag(tags))
result.add((T) e);
// Otherwise if only one of these parameters is necessary to select an element
if (!withTagsAndFlavors && ((!flavors.isEmpty() && matchesFlavor) || (!tags.isEmpty() && e.containsTag(tags))))
result.add((T) e);
}
}
return result;
}
/**
* This constructor tries to determine the entity type from the type argument used by a concrete implementation of
* GenericHibernateDao
.
*
* Note: This code will only work for immediate specialization, and especially not for subclasses.
*/
@SuppressWarnings("unchecked")
private Class getParametrizedType(Object object) {
Class current = getClass();
Type superclass;
Class extends T> entityClass = null;
while ((superclass = current.getGenericSuperclass()) != null) {
if (superclass instanceof ParameterizedType) {
entityClass = (Class) ((ParameterizedType) superclass).getActualTypeArguments()[0];
break;
} else if (superclass instanceof Class) {
current = (Class) superclass;
} else {
break;
}
}
if (entityClass == null) {
throw new IllegalStateException("Cannot determine entity type because " + getClass().getName()
+ " does not specify any type parameter.");
}
return entityClass;
}
/**
* Sets the flavors.
*
* Note that the order is relevant to the selection of the track returned by this selector.
*
* @param flavors
* the list of flavors
* @throws IllegalArgumentException
* if the flavors list is null
*/
public void setFlavors(List flavors) {
if (flavors == null)
throw new IllegalArgumentException("List of flavors must not be null");
this.flavors = flavors;
}
/**
* Adds the given flavor to the list of flavors.
*
* Note that the order is relevant to the selection of the track returned by this selector.
*
* @param flavor
*/
public void addFlavor(MediaPackageElementFlavor flavor) {
if (flavor == null)
throw new IllegalArgumentException("Flavor must not be null");
if (!flavors.contains(flavor))
flavors.add(flavor);
}
/**
* Adds the given flavor to the list of flavors.
*
* Note that the order is relevant to the selection of the track returned by this selector.
*
* @param flavor
*/
public void addFlavor(String flavor) {
if (flavor == null)
throw new IllegalArgumentException("Flavor must not be null");
MediaPackageElementFlavor f = MediaPackageElementFlavor.parseFlavor(flavor);
if (!flavors.contains(f))
flavors.add(f);
}
/**
* Adds the given flavor to the list of flavors.
*
* Note that the order is relevant to the selection of the track returned by this selector.
*
* @param index
* the position in the list
* @param flavor
* the flavor to add
*/
public void addFlavorAt(int index, MediaPackageElementFlavor flavor) {
if (flavor == null)
throw new IllegalArgumentException("Flavor must not be null");
flavors.add(index, flavor);
for (int i = index + 1; i < flavors.size(); i++) {
if (flavors.get(i).equals(flavor))
flavors.remove(i);
}
}
/**
* Adds the given flavor to the list of flavors.
*
* Note that the order is relevant to the selection of the track returned by this selector.
*
* @param index
* the position in the list
* @param flavor
* the flavor to add
*/
public void addFlavorAt(int index, String flavor) {
if (flavor == null)
throw new IllegalArgumentException("Flavor must not be null");
MediaPackageElementFlavor f = MediaPackageElementFlavor.parseFlavor(flavor);
flavors.add(index, f);
for (int i = index + 1; i < flavors.size(); i++) {
if (flavors.get(i).equals(f))
flavors.remove(i);
}
}
/**
* Removes all occurences of the given flavor from the list of flavors.
*
* @param flavor
* the flavor to remove
*/
public void removeFlavor(MediaPackageElementFlavor flavor) {
if (flavor == null)
throw new IllegalArgumentException("Flavor must not be null");
flavors.remove(flavor);
}
/**
* Removes all occurences of the given flavor from the list of flavors.
*
* @param flavor
* the flavor to remove
*/
public void removeFlavor(String flavor) {
if (flavor == null)
throw new IllegalArgumentException("Flavor must not be null");
flavors.remove(MediaPackageElementFlavor.parseFlavor(flavor));
}
/**
* Removes all occurences of the given flavor from the list of flavors.
*
* @param index
* the position in the list
*/
public void removeFlavorAt(int index) {
flavors.remove(index);
}
/**
* Returns the list of flavors.
*
* @return the flavors
*/
public MediaPackageElementFlavor[] getFlavors() {
return flavors.toArray(new MediaPackageElementFlavor[flavors.size()]);
}
/**
* Adds tag
to the list of tags that are used to select the media.
*
* @param tag
* the tag to include
*/
public void addTag(String tag) {
if (tag.startsWith(NEGATE_TAG_PREFIX)) {
excludeTags.add(tag.substring(NEGATE_TAG_PREFIX.length()));
} else {
tags.add(tag);
}
}
/**
* Adds tag
to the list of tags that are used to select the media.
*
* @param tag
* the tag to include
*/
public void removeTag(String tag) {
tags.remove(tag);
}
/**
* Returns the tags.
*
* @return the tags
*/
public String[] getTags() {
return tags.toArray(new String[tags.size()]);
}
/**
* Removes all of the tags from this selector.
*/
public void clearTags() {
tags.clear();
}
}