AssetDto.java

/*
 * 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.assetmanager.impl.persistence;

import org.opencastproject.util.MimeType;

import java.util.Optional;
import java.util.function.Function;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.TableGenerator;
import javax.persistence.TypedQuery;

/** JPA DTO modeling the asset database table. */
@Entity(name = "Asset")
@Table(name = "oc_assets_asset", indexes = {
    @Index(name = "IX_oc_assets_asset_checksum", columnList = ("checksum")),
    @Index(name = "IX_oc_assets_asset_mediapackage_element_id", columnList = ("mediapackage_element_id")) })
@NamedQueries({
    @NamedQuery(
        name = "Asset.findMediumByMpIdMpeIdAndVersion",
        query = "SELECT a, s.availability, s.organizationId FROM Asset a "
            + "JOIN a.snapshot s "
            + "WHERE s.mediaPackageId = :mpId "
            + "AND a.mediaPackageElementId = :mpeId "
            + "AND s.version = :version "
            + "ORDER BY s.version DESC"
    ),
    @NamedQuery(
        name = "Asset.findByChecksumStorageIdAndOrganizationId",
        query = "SELECT a FROM Asset a "
            + "INNER JOIN a.snapshot s "
            + "WHERE a.checksum = :checksum "
            + "AND a.storageId = :storageId "
            + "AND s.organizationId = :orgId "
    ),
    @NamedQuery(
        name = "Asset.updateStorageIdBySnapshot",
        query = "UPDATE Asset a SET a.storageId = :storageId "
            + "WHERE a.snapshot = :snapshot "
    ),
    @NamedQuery(
        name = "Asset.updateStorageIdBySnapshotAndMpElementId",
        query = "UPDATE Asset a SET a.storageId = :storageId "
            + "WHERE a.snapshot = :snapshot "
            + "AND a.mediaPackageElementId = :mediaPackageElementId "
    ),
    @NamedQuery(
        name = "Asset.countAssets",
        query = "SELECT COUNT(a) FROM Asset a "
    ),
})
// Maintain own generator to support database migrations from Archive to AssetManager
// The generator's initial value has to be set after the data migration.
// Otherwise duplicate key errors will most likely happen.
@TableGenerator(name = "seq_oc_assets_asset", initialValue = 0, allocationSize = 50)
public class AssetDto {

  @Id
  @GeneratedValue(strategy = GenerationType.TABLE, generator = "seq_oc_assets_asset")
  @Column(name = "id")
  private Long id;

  // foreign key referencing SnapshotDto.id
  @ManyToOne(targetEntity = SnapshotDto.class)
  @JoinColumn(name = "snapshot_id", referencedColumnName = "id", nullable = false)
  private SnapshotDto snapshot;

  @Column(name = "mediapackage_element_id", nullable = false, length = 128)
  private String mediaPackageElementId;

  @Column(name = "checksum", nullable = false, length = 64)
  private String checksum;

  @Column(name = "mime_type", nullable = true, length = 255)
  private String mimeType;

  @Column(name = "size", nullable = false)
  private Long size;

  @Column(name = "storage_id", nullable = false, length = 256)
  private String storageId;

  /**
   * Create a new DTO.
   */
  public static AssetDto mk(
      String mediaPackageElementId,
      SnapshotDto snapshot,
      String checksum,
      Optional<MimeType> mimeType,
      String storeageId,
      long size
  ) {
    final AssetDto dto = new AssetDto();
    dto.snapshot = snapshot;
    dto.mediaPackageElementId = mediaPackageElementId;
    dto.checksum = checksum;
    dto.mimeType = mimeType.isPresent() ? mimeType.get().toString() : null;
    dto.storageId = storeageId;
    dto.size = size;
    return dto;
  }

  public Long getId() {
    return id;
  }

  public String getMediaPackageElementId() {
    return mediaPackageElementId;
  }

  public String getChecksum() {
    return checksum;
  }

  public Optional<MimeType> getMimeType() {
    return Conversions.toMimeType(mimeType);
  }

  public Long getSize() {
    return size;
  }

  public String getStorageId() {
    return storageId;
  }

  void setStorageId(String storage) {
    this.storageId = storage;
  }

  public SnapshotDto getSnapshot() {
    return snapshot;
  }

  public void setSnapshot(SnapshotDto snapshot) {
    this.snapshot = snapshot;
  }

  /**
   * Count assets in the asset manager
   *
   * @return Number of assts
   */
  public static Function<EntityManager, Long> countAssetsQuery() {
    return em -> {
      TypedQuery<Long> query;
      query = em.createNamedQuery("Asset.countAssets", Long.class);
      return query.getSingleResult();
    };
  }

}