All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencastproject.mediapackage.MediaPackageSupport Maven / Gradle / Ivy

There is a newer version: 16.6
Show newest version
/*
 * 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;

import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.opencastproject.util.IoSupport.withResource;
import static org.opencastproject.util.data.Collections.list;
import static org.opencastproject.util.data.functions.Booleans.not;
import static org.opencastproject.util.data.functions.Options.sequenceOpt;
import static org.opencastproject.util.data.functions.Options.toOption;

import org.opencastproject.util.data.Effect;
import org.opencastproject.util.data.Function;
import org.opencastproject.util.data.Option;

import com.entwinemedia.fn.data.Opt;
import com.entwinemedia.fn.fns.Strings;

import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.net.URI;
import java.util.Collections;
import java.util.List;

/** Utility class used for media package handling. */
public final class MediaPackageSupport {
  /** Disable construction of this utility class */
  private MediaPackageSupport() {
  }

  private static final List NIL = java.util.Collections.EMPTY_LIST;

  /**
   * Mode used when merging media packages.
   * 

*

    *
  • Merge assigns a new identifier in case of conflicts
  • *
  • Replace replaces elements in the target media package with matching identifier
  • *
  • Skip skips elements from the source media package with matching identifer
  • *
  • Fail fail in case of conflicting identifier
  • *
*/ public enum MergeMode { Merge, Replace, Skip, Fail } /** the logging facility provided by log4j */ private static final Logger logger = LoggerFactory.getLogger(MediaPackageSupport.class.getName()); /** * Merges the contents of media package located at sourceDir into the media package located at * targetDir. *

* When choosing to move the media package element into the new place instead of copying them, the source media * package folder will be removed afterwards. *

* * @param dest * the target media package directory * @param src * the source media package directory * @param mode * conflict resolution strategy in case of identical element identifier * @throws MediaPackageException * if an error occurs either accessing one of the two media packages or merging them */ public static MediaPackage merge(MediaPackage dest, MediaPackage src, MergeMode mode) throws MediaPackageException { try { for (MediaPackageElement e : src.elements()) { if (dest.getElementById(e.getIdentifier()) == null) dest.add(e); else { if (MergeMode.Replace == mode) { logger.debug("Replacing element " + e.getIdentifier() + " while merging " + dest + " with " + src); dest.remove(dest.getElementById(e.getIdentifier())); dest.add(e); } else if (MergeMode.Skip == mode) { logger.debug("Skipping element " + e.getIdentifier() + " while merging " + dest + " with " + src); continue; } else if (MergeMode.Merge == mode) { logger.debug("Renaming element " + e.getIdentifier() + " while merging " + dest + " with " + src); e.setIdentifier(null); dest.add(e); } else if (MergeMode.Fail == mode) { throw new MediaPackageException("Target media package " + dest + " already contains element with id " + e.getIdentifier()); } } } } catch (UnsupportedElementException e) { throw new MediaPackageException(e); } return dest; } /** * Returns true if the media package contains an element with the specified identifier. * * @param identifier * the identifier * @return true if the media package contains an element with this identifier */ public static boolean contains(String identifier, MediaPackage mp) { for (MediaPackageElement element : mp.getElements()) { if (element.getIdentifier().equals(identifier)) return true; } return false; } /** * Extract the file name from a media package elements URI. * * @return the file name or none if it could not be determined */ public static Opt getFileName(MediaPackageElement mpe) { final URI uri = mpe.getURI(); if (uri != null) { return Opt.nul(FilenameUtils.getName(uri.toString())).bind(Strings.blankToNone); } else { return Opt.none(); } } /** * Create a copy of the given media package. *

* ATTENTION: Copying changes the type of the media package elements, e.g. an element of * type DublinCoreCatalog will become a CatalogImpl. */ public static MediaPackage copy(MediaPackage mp) { return (MediaPackage) mp.clone(); } /** Update a mediapackage element of a mediapackage. Mutates mp. */ public static void updateElement(MediaPackage mp, MediaPackageElement e) { mp.removeElementById(e.getIdentifier()); mp.add(e); } /** {@link #updateElement(MediaPackage, MediaPackageElement)} as en effect. */ public static Effect updateElement(final MediaPackage mp) { return new Effect() { @Override protected void run(MediaPackageElement e) { updateElement(mp, e); } }; } public static final Function getMediaPackageElementId = new Function() { @Override public String apply(MediaPackageElement mediaPackageElement) { return mediaPackageElement.getIdentifier(); } }; /** Filters and predicates to work with media package element collections. */ public static final class Filters { private Filters() { } // functions implemented for monadic bind in order to cast types public static Function> byType(final Class type) { return new Function>() { @Override public List apply(MediaPackageElement mpe) { return type.isAssignableFrom(mpe.getClass()) ? list((A) mpe) : (List) NIL; } }; } public static Function> byFlavor( final MediaPackageElementFlavor flavor) { return new Function>() { @Override public List apply(MediaPackageElement mpe) { // match is commutative return flavor.matches(mpe.getFlavor()) ? Collections.singletonList(mpe) : Collections.emptyList(); } }; } public static Function ofType(final Class type) { return new Function() { @Override public Boolean apply(MediaPackageElement mpe) { return type.isAssignableFrom(mpe.getClass()); } }; } public static final Function> presentations = byType(Publication.class); public static final Function> attachments = byType(Attachment.class); public static final Function> tracks = byType(Track.class); public static final Function> catalogs = byType(Catalog.class); public static final Function isPublication = ofType(Publication.class); public static final Function isNotPublication = not(isPublication); public static final Function hasChecksum = new Function() { @Override public Boolean apply(MediaPackageElement e) { return e.getChecksum() != null; } }; public static final Function hasNoChecksum = not(hasChecksum); public static final Function hasVideo = new Function() { @Override public Boolean apply(Track track) { return track.hasVideo(); } }; public static final Function hasAudio = new Function() { @Override public Boolean apply(Track track) { return track.hasAudio(); } }; public static final Function hasNoVideo = not(hasVideo); public static final Function hasNoAudio = not(hasAudio); /** Filters publications to channel channelId. */ public static Function ofChannel(final String channelId) { return new Function() { @Override public Boolean apply(Publication p) { return p.getChannel().equals(channelId); } }; } /** Check if mediapackage element has any of the given tags. */ public static Function hasTagAny(final List tags) { return new Function() { @Override public Boolean apply(MediaPackageElement mpe) { return mpe.containsTag(tags); } }; } /** * Return true if the element has a flavor that matches flavor. * * @see MediaPackageElementFlavor#matches(MediaPackageElementFlavor) */ public static Function matchesFlavor(final MediaPackageElementFlavor flavor) { return new Function() { @Override public Boolean apply(MediaPackageElement mpe) { // match is commutative return flavor.matches(mpe.getFlavor()); } }; } public static final Function> matchesFlavor = new Function>() { @Override public Function apply(final MediaPackageElementFlavor flavor) { return matchesFlavor(flavor); } }; public static final Function isEpisodeDublinCore = new Function() { @Override public Boolean apply(MediaPackageElement mpe) { // match is commutative return MediaPackageElements.EPISODE.matches(mpe.getFlavor()); } }; public static final Function isSmilCatalog = new Function() { @Override public Boolean apply(MediaPackageElement mpe) { // match is commutative return MediaPackageElements.SMIL.matches(mpe.getFlavor()); } }; } /** * Basic sanity checking for media packages. * *

   * // media package is ok
   * sanityCheck(mp).isNone()
   * 
* * @return none if the media package is a healthy condition, some([error_msgs]) otherwise */ public static Option> sanityCheck(MediaPackage mp) { final Option> errors = sequenceOpt(list(toOption(mp.getIdentifier() != null, "no ID"), toOption(mp.getIdentifier() != null && isNotBlank(mp.getIdentifier().toString()), "blank ID"))); return errors.getOrElse(NIL).size() == 0 ? Option.> none() : errors; } /** To be used in unit tests. */ public static MediaPackage loadFromClassPath(String path) { return withResource(MediaPackageSupport.class.getResourceAsStream(path), new Function.X() { @Override public MediaPackage xapply(InputStream is) throws MediaPackageException { return MediaPackageBuilderFactory.newInstance().newMediaPackageBuilder().loadFromXml(is); } }); } /** * Function to extract the ID of a media package. */ @Deprecated public static final Function getId = new Function() { @Override public String apply(MediaPackage mp) { return mp.getIdentifier().toString(); } }; /** Functions on media packages. */ public static final class Fn { private Fn() { } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy