@Indexable(type = IndexableType.REINDEX)
  @Override
  public Album moveAlbumToTrash(long userId, long albumId) throws PortalException {

    ServiceContext serviceContext = new ServiceContext();

    // Folder

    User user = userPersistence.findByPrimaryKey(userId);
    Date now = new Date();

    Album album = albumPersistence.findByPrimaryKey(albumId);

    int oldStatus = album.getStatus();

    album.setModifiedDate(serviceContext.getModifiedDate(now));
    album.setStatus(WorkflowConstants.STATUS_IN_TRASH);
    album.setStatusByUserId(user.getUserId());
    album.setStatusByUserName(user.getFullName());
    album.setStatusDate(serviceContext.getModifiedDate(now));

    albumPersistence.update(album);

    // Asset

    assetEntryLocalService.updateVisible(Album.class.getName(), album.getAlbumId(), false);

    // Trash

    TrashEntry trashEntry =
        trashEntryLocalService.addTrashEntry(
            userId,
            album.getGroupId(),
            Album.class.getName(),
            album.getAlbumId(),
            album.getUuid(),
            null,
            oldStatus,
            null,
            null);

    // Folders and entries

    List<Song> songs = songLocalService.getSongsByAlbumId(album.getAlbumId());

    moveDependentsToTrash(songs, trashEntry.getEntryId());

    return album;
  }
  public void deleteAlbums(long groupId) throws PortalException {
    List<Album> albums = getAlbums(groupId);

    for (Album album : albums) {
      albumLocalService.deleteAlbum(album.getAlbumId());
    }
  }
  @Indexable(type = IndexableType.REINDEX)
  @Override
  public Album restoreAlbumFromTrash(long userId, long albumId) throws PortalException {

    ServiceContext serviceContext = new ServiceContext();

    // Folder

    User user = userPersistence.findByPrimaryKey(userId);
    Date now = new Date();

    Album album = albumPersistence.findByPrimaryKey(albumId);

    TrashEntry trashEntry = trashEntryLocalService.getEntry(Album.class.getName(), albumId);

    album.setModifiedDate(serviceContext.getModifiedDate(now));
    album.setStatus(trashEntry.getStatus());
    album.setStatusByUserId(user.getUserId());
    album.setStatusByUserName(user.getFullName());
    album.setStatusDate(serviceContext.getModifiedDate(now));

    albumPersistence.update(album);

    assetEntryLocalService.updateVisible(Album.class.getName(), album.getAlbumId(), true);

    // Songs

    List<Song> songs =
        songLocalService.getSongsByAlbumId(
            album.getGroupId(), album.getAlbumId(), WorkflowConstants.STATUS_IN_TRASH);

    restoreDependentsFromTrash(songs, trashEntry.getEntryId());

    // Trash

    trashEntryLocalService.deleteEntry(trashEntry.getEntryId());

    return album;
  }
  @Override
  public void addEntryResources(Album album, String[] groupPermissions, String[] guestPermissions)
      throws PortalException {

    resourceLocalService.addModelResources(
        album.getCompanyId(),
        album.getGroupId(),
        album.getUserId(),
        Album.class.getName(),
        album.getAlbumId(),
        groupPermissions,
        guestPermissions);
  }
  @Override
  public void addEntryResources(
      Album album, boolean addGroupPermissions, boolean addGuestPermissions)
      throws PortalException {

    resourceLocalService.addResources(
        album.getCompanyId(),
        album.getGroupId(),
        album.getUserId(),
        Album.class.getName(),
        album.getAlbumId(),
        false,
        addGroupPermissions,
        addGuestPermissions);
  }
  @Indexable(type = IndexableType.DELETE)
  public Artist deleteArtist(long artistId) throws PortalException {
    Artist artist = artistPersistence.findByPrimaryKey(artistId);

    List<Album> albums = albumLocalService.getAlbumsByArtistId(artistId);

    for (Album album : albums) {
      albumLocalService.deleteAlbum(album.getAlbumId());
    }

    try {
      PortletFileRepositoryUtil.deletePortletFileEntry(
          artist.getGroupId(),
          DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
          String.valueOf(artistId));
    } catch (Exception e) {
    }

    return artistPersistence.remove(artistId);
  }
  public void updateAsset(
      long userId,
      Album album,
      long[] assetCategoryIds,
      String[] assetTagNames,
      long[] assetLinkEntryIds)
      throws PortalException {

    AssetEntry assetEntry =
        assetEntryLocalService.updateEntry(
            userId,
            album.getGroupId(),
            album.getCreateDate(),
            album.getModifiedDate(),
            Album.class.getName(),
            album.getAlbumId(),
            album.getUuid(),
            0,
            assetCategoryIds,
            assetTagNames,
            true,
            null,
            null,
            null,
            ContentTypes.TEXT_HTML,
            album.getName(),
            null,
            null,
            null,
            null,
            0,
            0,
            null,
            false);

    assetLinkLocalService.updateLinks(
        userId, assetEntry.getEntryId(), assetLinkEntryIds, AssetLinkConstants.TYPE_RELATED);
  }
  @Indexable(type = IndexableType.REINDEX)
  public Album addAlbum(
      long userId,
      long artistId,
      String name,
      int year,
      InputStream inputStream,
      ServiceContext serviceContext)
      throws PortalException {

    long groupId = serviceContext.getScopeGroupId();

    User user = userPersistence.findByPrimaryKey(userId);

    Date now = new Date();

    validate(name);

    long albumId = counterLocalService.increment();

    Album album = albumPersistence.create(albumId);

    album.setUuid(serviceContext.getUuid());
    album.setGroupId(groupId);
    album.setCompanyId(user.getCompanyId());
    album.setUserId(user.getUserId());
    album.setUserName(user.getFullName());
    album.setCreateDate(serviceContext.getCreateDate(now));
    album.setModifiedDate(serviceContext.getModifiedDate(now));
    album.setArtistId(artistId);
    album.setName(name);
    album.setYear(year);
    album.setExpandoBridgeAttributes(serviceContext);

    albumPersistence.update(album);

    if (inputStream != null) {
      PortletFileRepositoryUtil.addPortletFileEntry(
          groupId,
          userId,
          Album.class.getName(),
          album.getAlbumId(),
          Constants.JUKEBOX_PORTLET_REPOSITORY,
          DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
          inputStream,
          String.valueOf(album.getAlbumId()),
          StringPool.BLANK,
          true);
    }

    // Resources

    if (serviceContext.isAddGroupPermissions() || serviceContext.isAddGuestPermissions()) {

      addEntryResources(
          album, serviceContext.isAddGroupPermissions(), serviceContext.isAddGuestPermissions());
    } else {
      addEntryResources(
          album, serviceContext.getGroupPermissions(), serviceContext.getGuestPermissions());
    }

    // Message boards

    mbMessageLocalService.addDiscussionMessage(
        userId,
        album.getUserName(),
        groupId,
        Album.class.getName(),
        albumId,
        WorkflowConstants.ACTION_PUBLISH);

    // Asset

    updateAsset(
        userId,
        album,
        serviceContext.getAssetCategoryIds(),
        serviceContext.getAssetTagNames(),
        serviceContext.getAssetLinkEntryIds());

    return album;
  }
  @Indexable(type = IndexableType.REINDEX)
  public Album updateAlbum(
      long userId,
      long albumId,
      long artistId,
      String name,
      int year,
      InputStream inputStream,
      ServiceContext serviceContext)
      throws PortalException {

    // Event

    User user = userPersistence.findByPrimaryKey(userId);

    validate(name);

    Album album = albumPersistence.findByPrimaryKey(albumId);

    album.setModifiedDate(serviceContext.getModifiedDate(null));
    album.setArtistId(artistId);
    album.setName(name);
    album.setYear(year);
    album.setExpandoBridgeAttributes(serviceContext);

    albumPersistence.update(album);

    if (inputStream != null) {
      Repository repository =
          PortletFileRepositoryUtil.fetchPortletRepository(
              serviceContext.getScopeGroupId(), Constants.JUKEBOX_PORTLET_REPOSITORY);

      if (repository != null) {
        try {
          PortletFileRepositoryUtil.deletePortletFileEntry(
              repository.getRepositoryId(),
              DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
              String.valueOf(album.getAlbumId()));
        } catch (Exception e) {
          if (_log.isDebugEnabled()) {
            _log.debug("Cannot delete album cover");
          }
        }
      }

      PortletFileRepositoryUtil.addPortletFileEntry(
          serviceContext.getScopeGroupId(),
          userId,
          Album.class.getName(),
          album.getAlbumId(),
          Constants.JUKEBOX_PORTLET_REPOSITORY,
          DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
          inputStream,
          String.valueOf(album.getAlbumId()),
          StringPool.BLANK,
          true);
    }

    // Asset

    updateAsset(
        userId,
        album,
        serviceContext.getAssetCategoryIds(),
        serviceContext.getAssetTagNames(),
        serviceContext.getAssetLinkEntryIds());

    return album;
  }