org.tinymediamanager.core.tvshow.TvShowModuleManager.java Source code

Java tutorial

Introduction

Here is the source code for org.tinymediamanager.core.tvshow.TvShowModuleManager.java

Source

/*
 * Copyright 2012 - 2016 Manuel Laggner
 *
 * Licensed under the Apache 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://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.tinymediamanager.core.tvshow;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.TimeZone;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.h2.mvstore.MVMap;
import org.h2.mvstore.MVStore;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tinymediamanager.Globals;
import org.tinymediamanager.core.Constants;
import org.tinymediamanager.core.ITmmModule;
import org.tinymediamanager.core.Settings;
import org.tinymediamanager.core.Utils;
import org.tinymediamanager.core.tvshow.entities.TvShow;
import org.tinymediamanager.core.tvshow.entities.TvShowEpisode;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;

/**
 * The class TvShowModuleManager. Used to manage the tv show module
 * 
 * @author Manuel Laggner
 */
public class TvShowModuleManager implements ITmmModule {
    public static final TvShowSettings SETTINGS = Globals.settings.getTvShowSettings();

    private static final String MODULE_TITLE = "TV show management";
    private static final String TV_SHOW_DB = "tvshows.db";
    private static final Logger LOGGER = LoggerFactory.getLogger(TvShowModuleManager.class);
    private static TvShowModuleManager instance;

    private boolean enabled;
    private MVStore mvStore;
    private ObjectMapper objectMapper;
    private ObjectWriter tvShowObjectWriter;
    private ObjectWriter episodeObjectWriter;

    private MVMap<UUID, String> tvShowMap;
    private MVMap<UUID, String> episodeMap;

    private TvShowModuleManager() {
        enabled = false;
    }

    public static TvShowModuleManager getInstance() {
        if (instance == null) {
            instance = new TvShowModuleManager();
        }
        return instance;
    }

    @Override
    public String getModuleTitle() {
        return MODULE_TITLE;
    }

    @Override
    public void startUp() throws Exception {
        // do a DB backup, and keep last 15 copies
        Path db = Paths.get(Settings.getInstance().getSettingsFolder(), TV_SHOW_DB);
        Utils.createBackupFile(db);
        Utils.deleteOldBackupFile(db, 15);

        // configure database
        mvStore = new MVStore.Builder()
                .fileName(Paths.get(Settings.getInstance().getSettingsFolder(), TV_SHOW_DB).toString())
                .compressHigh().backgroundExceptionHandler(new Thread.UncaughtExceptionHandler() {
                    @Override
                    public void uncaughtException(Thread t, Throwable e) {
                        LOGGER.error("Error in the background thread of the persistent cache", e);
                    }
                }).autoCommitBufferSize(4096).open();
        mvStore.setAutoCommitDelay(2000); // 2 sec
        mvStore.setRetentionTime(0);
        mvStore.setReuseSpace(true);

        // configure JSON
        objectMapper = new ObjectMapper();
        objectMapper.configure(MapperFeature.AUTO_DETECT_GETTERS, false);
        objectMapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS, false);
        objectMapper.configure(MapperFeature.AUTO_DETECT_SETTERS, false);
        objectMapper.configure(MapperFeature.AUTO_DETECT_FIELDS, false);
        objectMapper.setTimeZone(TimeZone.getDefault());
        objectMapper.setSerializationInclusion(Include.NON_DEFAULT);

        tvShowObjectWriter = objectMapper.writerFor(TvShow.class);
        episodeObjectWriter = objectMapper.writerFor(TvShowEpisode.class);

        tvShowMap = mvStore.openMap("tvshows");
        episodeMap = mvStore.openMap("episodes");

        TvShowList.getInstance().loadTvShowsFromDatabase(tvShowMap, objectMapper);
        TvShowList.getInstance().loadEpisodesFromDatabase(episodeMap, objectMapper);
        TvShowList.getInstance().initDataAfterLoading();
        enabled = true;
    }

    @Override
    public void shutDown() throws Exception {
        mvStore.compactMoveChunks();
        mvStore.close();

        enabled = false;

        if (Globals.settings.isDeleteTrashOnExit()) {
            for (String ds : SETTINGS.getTvShowDataSource()) {
                Path file = Paths.get(ds, Constants.BACKUP_FOLDER);
                Utils.deleteDirectoryRecursive(file);
            }
        }
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }

    /**
     * dumps a whole tvshow to logfile
     * 
     * @param tvshow
     *          the TV show to dump the data for
     */
    public void dump(TvShow tvshow) {
        try {
            JSONObject show = new JSONObject(tvShowObjectWriter.writeValueAsString(tvshow));
            JSONArray episodes = new JSONArray();
            for (TvShowEpisode ep : tvshow.getEpisodes()) {
                JSONObject epJson = new JSONObject(episodeObjectWriter.writeValueAsString(ep));
                episodes.put(epJson);
            }
            show.put("episodes", episodes);
            LOGGER.info("Dumping TvShow:\n" + show.toString(4));
        } catch (JsonProcessingException e) {
            LOGGER.error("Cannot parse JSON!", e);
        }
    }

    void persistTvShow(TvShow tvShow) throws Exception {
        String newValue = tvShowObjectWriter.writeValueAsString(tvShow);
        String oldValue = tvShowMap.get(tvShow.getDbId());

        if (!StringUtils.equals(newValue, oldValue)) {
            // write to DB
            tvShowMap.put(tvShow.getDbId(), newValue);
        }
    }

    void removeTvShowFromDb(TvShow tvShow) throws Exception {
        tvShowMap.remove(tvShow.getDbId());
    }

    void persistEpisode(TvShowEpisode episode) throws Exception {
        String newValue = episodeObjectWriter.writeValueAsString(episode);
        String oldValue = episodeMap.get(episode.getDbId());

        if (!StringUtils.equals(newValue, oldValue)) {
            episodeMap.put(episode.getDbId(), newValue);
        }
    }

    void removeEpisodeFromDb(TvShowEpisode episode) throws Exception {
        episodeMap.remove(episode.getDbId());
    }

    @Override
    public void initializeDatabase() throws Exception {
        Utils.deleteFileSafely(Paths.get(Settings.getInstance().getSettingsFolder(), TV_SHOW_DB));
    }
}