Package primarydatamanager

Source Code of primarydatamanager.RawDataProcessor

/*
* TV-Browser
* Copyright (C) 04-2003 Martin Oberhauser (darras@users.sourceforge.net)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
* CVS information:
*  $RCSfile$
*   $Source$
*     $Date: 2011-03-23 19:39:07 +0100 (Wed, 23 Mar 2011) $
*   $Author: bananeweizen $
* $Revision: 6963 $
*/
package primarydatamanager;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.logging.Logger;

import tvbrowserdataservice.file.ChannelList;
import tvbrowserdataservice.file.DayProgramFile;
import tvbrowserdataservice.file.ProgramField;
import tvbrowserdataservice.file.ProgramFrame;
import tvdataservice.MutableProgram;
import util.io.FileFormatException;
import util.io.IOUtilities;
import devplugin.Channel;
import devplugin.Date;
import devplugin.ProgramFieldType;

/**
* Compares the new raw data with the last prepared data and creates update
* files if nessesary.
*
* @author Til Schneider, www.murfman.de
*/
public class RawDataProcessor {

  private static final Logger mLog = Logger.getLogger(RawDataProcessor.class.getName());

  /**
   * @deprecated use #{tvdataservice.MutableProgram#MAX_SHORT_INFO_LENGTH}
   */
  final public static int MAX_SHORT_DESCRIPTION_LENGTH = MutableProgram.MAX_SHORT_INFO_LENGTH;

  /**
   * The percentage of the number of frames that must stay in the version
   * of a program to come into quarantine.
   */
  private static double MAX_DELETED_FRAMES = 0.25;

  /**
   * The deadline day. All data files that contain TV data for days before that
   * day count as outdated.
   */
  private Date mDeadlineDay;

  private HashSet<String> mForceCompleteUpdateChannelSet;

  private int mQuarantineCount;


  public RawDataProcessor() {
    mDeadlineDay = new Date().addDays(-2);
  }


  public void forceCompleteUpdateFor(String channel) {
    if (mForceCompleteUpdateChannelSet == null) {
      mForceCompleteUpdateChannelSet = new HashSet<String>();
    }

    mForceCompleteUpdateChannelSet.add(channel);
  }


  public int getQuarantineCount() {
    return mQuarantineCount;
  }


  public void processRawDataDir(File rawDir, File preparedDir, File workDir, ChannelList channelList)
    throws PreparationException
  {
    if (! rawDir.exists()) {
      throw new PreparationException("Raw directory does not exist: "
        + rawDir.getAbsolutePath());
    }

    // Go through the raw files and process them one by one
    File[] fileArr = rawDir.listFiles();
    if (fileArr == null) {
      return;
    }
    for (File element : fileArr) {
      String fileName = element.getName();

      // Extract the information from the file name
      // Pattern: <yyyy>-<mm>-<dd>_<country>_<channel>_raw_full.prog.gz
      if (fileName.endsWith("_raw_full.prog.gz")) {
        // Extract the information from the file name
        Date date;
        String country, channel;
        try {
          int year = Integer.parseInt(fileName.substring(0, 4));
          int month = Integer.parseInt(fileName.substring(5, 7));
          int day = Integer.parseInt(fileName.substring(8, 10));
          date = new Date(year, month, day);

          int countryEnd = fileName.indexOf('_', 11);
          country = fileName.substring(11, countryEnd);

          int channelEnd = fileName.indexOf('_', countryEnd + 1);
          channel = fileName.substring(countryEnd + 1, channelEnd);

          // if the file does not belong to our group, we ignore it
          if (!RawDataProcessor.channelBelongsToGroup(channelList, channel, country)) {
            continue;
          }

        }
        catch (Exception exc) {
          throw new PreparationException("Raw file name has wrong pattern: "
            + fileName, exc);
        }

        // Ensure that the file is not outdated
        if (date.compareTo(mDeadlineDay) >= 0) {
          // Load the file
          DayProgramFile rawFile;
          try {
            rawFile = new DayProgramFile();
            rawFile.readFromFile(element);
          }
          catch (Exception exc) {
            throw new PreparationException("Loading raw file failed: "
              + fileName, exc);
          }

          // Process the file
          try {
            processRawFile(rawFile, date, country, channel, preparedDir, workDir);
          }
          catch (PreparationException exc) {
            throw new PreparationException("Processing raw file failed: "
              + element.getAbsolutePath(), exc);
          }
        }
        else {
          element.delete();
        }
      }
    }

  }

  public static boolean channelBelongsToGroup(ChannelList list, String channelId, String country) {

      for (int i=0; i<list.getChannelCount(); i++) {
        Channel ch = list.getChannelAt(i);
        if (ch.getId().equals(channelId) && ch.getCountry().equals(country)) {
          return true;
        }
      }
        return false;
    }


  private void processRawFile(DayProgramFile rawProg, Date date,
    String country, String channel, File preparedDir, File workDir)
    throws PreparationException
  {

    System.out.println(date+"; "+channel+"...");


    // Prepare the raw file (check mandatory fields, remove empty fields, ...)
    prepareDayProgram(rawProg, date, country, channel);

    // Get the file names of the level-complete-files
    String[] levelFileNameArr = new String[DayProgramFile.getLevels().length];
    for (int i = 0; i < levelFileNameArr.length; i++) {
      levelFileNameArr[i] = DayProgramFile.getProgramFileName(date, country,
        channel, DayProgramFile.getLevels()[i].getId());
    }

    // Load the level files if they exist
    DayProgramFile[] levelProgArr = new DayProgramFile[levelFileNameArr.length];
    for (int i = 0; i < levelProgArr.length; i++) {
      File file = new File(preparedDir, levelFileNameArr[i]);
      System.err.println(file);
      if (file.exists()) {
        levelProgArr[i] = new DayProgramFile();
        try {
          levelProgArr[i].readFromFile(file);
        }
        catch (Exception exc) {
          throw new PreparationException("Loading complete file for level "
            + DayProgramFile.getLevels()[i] + " failed: " + levelFileNameArr[i],
            exc);
        }
      }
    }

    // Create a file that contains all level files
    DayProgramFile preparedProg = new DayProgramFile();
    for (int i = 0; i < levelProgArr.length; i++) {
      if (levelProgArr[i] != null) {
        try {
          preparedProg.merge(levelProgArr[i]);
        }
        catch (FileFormatException exc) {
          throw new PreparationException("Complete file has wrong format: "
            + preparedDir + File.separator + levelFileNameArr[i], exc);
        }
      }
    }

    // Map the programs of the raw file to the programs of the prepared file
    // in order to give them the right IDs
    mapDayProgram(rawProg, preparedProg, date, country, channel, preparedDir);

    // Check whether the new version should be in quarantine
    File targetDir = workDir;
    boolean quarantine = checkForQuarantine(preparedProg, rawProg);
    if (quarantine) {
      mLog.warning("Putting day program file in quarantine: "
        + date + ", " + country + ", " + channel);
      mQuarantineCount++;

      targetDir = new File(workDir, "quarantine");
      if (! targetDir.exists()) {
        targetDir.mkdir();
      }
    }

    // Split the raw file in the levels
    DayProgramFile[] newLevelProgArr
      = new DayProgramFile[DayProgramFile.getLevels().length];
    for (int i = 0; i < newLevelProgArr.length; i++) {
      newLevelProgArr[i] = extractLevel(rawProg, i);
    }

    // Write the files into the work dir
    for (int i = 0; i < newLevelProgArr.length; i++) {
      if (levelProgArr[i] == null) {
        // We don't have an old program file
        // -> Create a new complete file if we have data now
        if (newLevelProgArr[i].getProgramFrameCount() != 0) {
          File file = new File(targetDir, levelFileNameArr[i]);
          try {
            newLevelProgArr[i].writeToFile(file);

            mLog.fine("Created new day program file: " + levelFileNameArr[i]);
          }
          catch (Exception exc) {
            throw new PreparationException("Writing prepared file failed: "
              + file.getAbsolutePath(), exc);
          }
        }
      } else {
        // We already have an old program file

        // Check whether the new version should come into quarantine
        String level = DayProgramFile.getLevels()[i].getId();
        if (quarantine) {
          // Copy the old files
          copyFiles(levelProgArr[i], date, country, channel, level,
            preparedDir, workDir);
        }

        // Check whether something changed
        if (levelProgArr[i].equals(newLevelProgArr[i])) {
          // Nothing changed -> Just copy the files
          copyFiles(levelProgArr[i], date, country, channel, level,
            preparedDir, targetDir);

          mLog.finest("Nothing to do for day program file: " + levelFileNameArr[i]);
        } else {
          // Something changed -> Create an update
          createUpdate(levelProgArr[i], newLevelProgArr[i], date, country,
                       channel, level, preparedDir, targetDir);

          mLog.finest("Updated day program file to version "
            + (levelProgArr[i].getVersion() + 1) + ": " + levelFileNameArr[i]);
        }
      }
    }
  }


  /**
   * Prepares a day program.
   * <p>
   * Checks mandatory fields, removes empty fields, ...
   */
  private void prepareDayProgram(DayProgramFile prog, Date date,
    String country, String channel)
    throws PreparationException
  {
    // Go through the program frames and pepare them
    for (int frameIdx = 0; frameIdx < prog.getProgramFrameCount(); frameIdx++) {
      ProgramFrame frame = prog.getProgramFrameAt(frameIdx);

      // Trim text fields and remove all empty fields from the day program
      for (int fieldIdx = frame.getProgramFieldCount() - 1; fieldIdx >= 0; fieldIdx--) {
        ProgramField field = frame.getProgramFieldAt(fieldIdx);

        // Trim text fields
        if (field.getType().getFormat() == ProgramFieldType.TEXT_FORMAT) {
          String oldText = field.getTextData();
          if (oldText != null) {
            String newText = oldText.trim();
            if (oldText.length() != newText.length()) {
              field.setTextData(newText);
            }
          }
        }

        // Remove empty fields
        byte[] data = field.getBinaryData();
        if ((data == null) || (data.length == 0)) {
          frame.removeProgramFieldAt(fieldIdx);
        }
      }

      // Check the mandatory fields (start time and title)
      ProgramField startTimeField = frame.getProgramFieldOfType(ProgramFieldType.START_TIME_TYPE);
      if (startTimeField == null) {
        throw new PreparationException("Program frame has no start time. "
          + "ID: " + frame.getId() + ", Day program: " + date + ", " + country + ", " + channel);
      }
      ProgramField titleField = frame.getProgramFieldOfType(ProgramFieldType.TITLE_TYPE);
      if (titleField == null) {
        frame.addProgramField(ProgramField.create(ProgramFieldType.TITLE_TYPE, "[Unknown title]"));
        System.out.println("Program frame has no title. "
          + "ID: " + frame.getId() + ", Day program: " + date + ", " + country + ", " + channel);
      }

      // Try to create a short description
      ProgramField shortDescField = frame.getProgramFieldOfType(ProgramFieldType.SHORT_DESCRIPTION_TYPE);
      if (shortDescField == null) {
        ProgramField descField = frame.getProgramFieldOfType(ProgramFieldType.DESCRIPTION_TYPE);
        if (descField != null) {
          // Generate a short description from the description
          String shortDesc = descField.getTextData();
          if (shortDesc.length() > MutableProgram.MAX_SHORT_INFO_LENGTH) {
            int lastSpacePos = shortDesc.lastIndexOf(' ', MutableProgram.MAX_SHORT_INFO_LENGTH);
            if (lastSpacePos == -1) {
              shortDesc = shortDesc.substring(0, MutableProgram.MAX_SHORT_INFO_LENGTH);
            } else {
              shortDesc = shortDesc.substring(0, lastSpacePos);
            }
          }

          // Add the short description to the frame
          shortDescField = ProgramField.create(ProgramFieldType.SHORT_DESCRIPTION_TYPE, shortDesc);
          frame.addProgramField(shortDescField);
        }
      }
    }
  }


  private void mapDayProgram(DayProgramFile rawProg, DayProgramFile preparedFile,
    Date date, String country, String channel, File preparedDir)
    throws PreparationException
  {
    // Map the programs
    if ((mForceCompleteUpdateChannelSet != null)
      && mForceCompleteUpdateChannelSet.contains(channel))
    {
      // We should force a complete update for this channel
      // We do this by giving each program in the rawProg a ID of -1.
      // This way, it will get a new ID
      mLog.warning("Forcing complete update for Day program: " + date + ", "
        + country + ", " + channel);

      for (int i = 0; i < rawProg.getProgramFrameCount(); i++) {
        rawProg.getProgramFrameAt(i).setId(-1);
      }
    } else {
      new DayProgramMapper().map(rawProg, preparedFile);
    }

    // Check whether we have programs that did not find a match
    boolean someProgramsAreUnmapped = false;
    for (int i = 0; i < rawProg.getProgramFrameCount(); i++) {
      if (rawProg.getProgramFrameAt(i).getId() == -1) {
        someProgramsAreUnmapped = true;
        break;
      }
    }

    // If we have unmapped programs -> give them new IDs
    if (someProgramsAreUnmapped) {
      // Get the maximum ID from the complete file and all update files
      int maxId = PrimaryDataUtilities.getMaxId(preparedFile);
      for (int i = 0; i < DayProgramFile.getLevels().length; i++) {
        String level = DayProgramFile.getLevels()[i].getId();
        int updateMaxId = getMaxIdOfUpdateFiles(date, country, channel, level,
                                                preparedDir);
        if (updateMaxId > maxId) {
          maxId = updateMaxId;
        }
      }

      int nextId = maxId + 1;
      for (int i = 0; i < rawProg.getProgramFrameCount(); i++) {
        ProgramFrame frame = rawProg.getProgramFrameAt(i);
        if (frame.getId() == -1) {
          frame.setId(nextId++);
        }
      }
    }
  }


  private DayProgramFile extractLevel(DayProgramFile prog, int levelIdx)
    throws PreparationException
  {
    DayProgramFile levelProg = new DayProgramFile();

    for (int i = 0; i < prog.getProgramFrameCount(); i++) {
      ProgramFrame frame = prog.getProgramFrameAt(i);
      ProgramFrame levelFrame = null;

      if (levelIdx == 0) {
        // base: All information but description and the image
        levelFrame = (ProgramFrame) frame.clone();
        levelFrame.removeProgramFieldOfType(ProgramFieldType.DESCRIPTION_TYPE);
        levelFrame.removeProgramFieldOfType(ProgramFieldType.ACTOR_LIST_TYPE);
        levelFrame.removeProgramFieldOfType(ProgramFieldType.ADDITIONAL_INFORMATION_TYPE);
       // levelFrame.removeProgramFieldOfType(ProgramFieldType.IMAGE_TYPE);
        levelFrame.removeProgramFieldOfType(ProgramFieldType.PICTURE_TYPE);
        levelFrame.removeProgramFieldOfType(ProgramFieldType.PICTURE_DESCRIPTION_TYPE);
        levelFrame.removeProgramFieldOfType(ProgramFieldType.PICTURE_COPYRIGHT_TYPE);

      } else {
        ProgramField levelField1 = null;
        ProgramField levelField2 = null;
        ProgramField levelField3 = null;

        switch (levelIdx) {
          case 1:
            // more00-16: Only the descriptions and the actor list
            //            between midnight and 16 pm
            if (PrimaryDataUtilities.getProgramStartTime(frame) < (16 * 60)) {
              levelField1 = frame.getProgramFieldOfType(ProgramFieldType.DESCRIPTION_TYPE);
              levelField2 = frame.getProgramFieldOfType(ProgramFieldType.ACTOR_LIST_TYPE);
              levelField3 = frame.getProgramFieldOfType(ProgramFieldType.ADDITIONAL_INFORMATION_TYPE);
            }
            break;
          case 2:
            // more16-00: Only the descriptions and the actor list
            //            between 16 pm and midnight
            if (PrimaryDataUtilities.getProgramStartTime(frame) >= (16 * 60)) {
              levelField1 = frame.getProgramFieldOfType(ProgramFieldType.DESCRIPTION_TYPE);
              levelField2 = frame.getProgramFieldOfType(ProgramFieldType.ACTOR_LIST_TYPE);
              levelField3 = frame.getProgramFieldOfType(ProgramFieldType.ADDITIONAL_INFORMATION_TYPE);
            }
            break;
         /* case 3:
            // image00-16: Only the image between midnight and 16 pm
            if (PrimaryDataUtilities.getProgramStartTime(frame) < (16 * 60)) {
              levelField1 = frame.getProgramFieldOfType(ProgramFieldType.IMAGE_TYPE);
            }
            break;
          case 4:
            // image16-00: Only the image between 16 pm and midnight
            if (PrimaryDataUtilities.getProgramStartTime(frame) >= (16 * 60)) {
              levelField1 = frame.getProgramFieldOfType(ProgramFieldType.IMAGE_TYPE);
            }
            break;*/

          case 3:
            // picture00-16: Only the picture between midnight and 16 pm
            if (PrimaryDataUtilities.getProgramStartTime(frame) < (16 * 60)) {
              levelField1 = frame.getProgramFieldOfType(ProgramFieldType.PICTURE_TYPE);
              levelField2 = frame.getProgramFieldOfType(ProgramFieldType.PICTURE_DESCRIPTION_TYPE);
              levelField3 = frame.getProgramFieldOfType(ProgramFieldType.PICTURE_COPYRIGHT_TYPE);
            }
            break;

          case 4:
            // picture16-00: Only the picture between 16 pm and midnight
            if (PrimaryDataUtilities.getProgramStartTime(frame) >= (16 * 60)) {
              levelField1 = frame.getProgramFieldOfType(ProgramFieldType.PICTURE_TYPE);
              levelField2 = frame.getProgramFieldOfType(ProgramFieldType.PICTURE_DESCRIPTION_TYPE);
              levelField3 = frame.getProgramFieldOfType(ProgramFieldType.PICTURE_COPYRIGHT_TYPE);
            }
            break;


        }

        if ((levelField1 != null) || (levelField2 != null) || (levelField3 != null)) {
          levelFrame = new ProgramFrame(frame.getId());
          if (levelField1 != null) {
            levelFrame.addProgramField(levelField1);
          }
          if (levelField2 != null) {
            levelFrame.addProgramField(levelField2);
          }
          if (levelField3 != null) {
            levelFrame.addProgramField(levelField3);
          }
        }
      }

      if (levelFrame != null) {
        levelProg.addProgramFrame(levelFrame);
      }
    }

    return levelProg;
  }


  private void copyFiles(DayProgramFile prog, Date date, String country,
    String channel, String level, File fromDir, File toDir)
    throws PreparationException
  {
    // Copy the complete file
    String fileName = DayProgramFile.getProgramFileName(date, country, channel, level);
    String additionalName = fileName.substring(0,fileName.indexOf(".prog.gz")) + "_additional.prog.gz";

    File prepFile = new File(fromDir, fileName);
    File additionalFile = new File(fromDir, additionalName);
    File workFile = new File(toDir, fileName);
    try {
      IOUtilities.copy(prepFile, workFile);

      if(additionalFile.isFile()) {
        IOUtilities.copy(additionalFile, new File(toDir, additionalName));
      }
    }
    catch (IOException exc) {
      throw new PreparationException("Copying complete file from '"
        + prepFile.getAbsolutePath() + "' to '" + workFile.getAbsolutePath()
        + "' failed!", exc);
    }

    // Copy the update files
    for (int version = 1; version < prog.getVersion(); version++) {
      fileName = DayProgramFile.getProgramFileName(date, country, channel, level, version);
      prepFile = new File(fromDir, fileName);
      workFile = new File(toDir, fileName);
      try {
        IOUtilities.copy(prepFile, workFile);
      }
      catch (IOException exc) {
        throw new PreparationException("Copying update file #" + version + " from '"
          + prepFile.getAbsolutePath() + "' to '" + workFile.getAbsolutePath()
          + "' failed!", exc);
      }
    }
  }


  private void createUpdate(DayProgramFile lastProg, DayProgramFile newProg,
    Date date, String country, String channel, String level, File preparedDir,
    File targetDir)
    throws PreparationException
  {
    newProg.setVersion(lastProg.getVersion() + 1);
    String completeFilename = DayProgramFile.getProgramFileName(date, country,
      channel, level);
    File file = new File(targetDir, completeFilename);
    try {
      newProg.writeToFile(file);
    }
    catch (Exception exc) {
      throw new PreparationException("Writing complete file failed: "
        + file.getAbsolutePath(), exc);
    }

    // Create the new update file that updates from the last version to the
    // new version
    DayProgramFile newUpdateFile = createUpdateFile(lastProg, newProg);

    // Save the update file
    String newUpdateFileName = DayProgramFile.getProgramFileName(date, country,
      channel, level, lastProg.getVersion());
    file = new File(targetDir, newUpdateFileName);
    try {
      newUpdateFile.writeToFile(file);
    }
    catch (Exception exc) {
      throw new PreparationException("Writing new update file failed: "
        + file.getAbsolutePath(), exc);
    }

    // Update the other update files
    updateOldUpdateFiles(newUpdateFile, date, country, channel, level,
                         preparedDir, targetDir);
  }


  private DayProgramFile createUpdateFile(DayProgramFile lastCompleteFile,
    DayProgramFile newCompleteFile)
  {
    DayProgramFile updateFile = new DayProgramFile();
    updateFile.setVersion(newCompleteFile.getVersion());

    // Determine the programs that should be deleted
    for (int lastIdx = 0; lastIdx < lastCompleteFile.getProgramFrameCount(); lastIdx++) {
      int id = lastCompleteFile.getProgramFrameAt(lastIdx).getId();

      // Check whether this frame has an counterpart in the new file
      int newIdx = newCompleteFile.getProgramFrameIndexForId(id);
      if (newIdx == -1) {
        // It has not -> Add an empty frame with this ID as a order for deletion
        ProgramFrame frame = new ProgramFrame(id);
        updateFile.addProgramFrame(frame);
      }
    }

    // Determine the programs that should be inserted or updated
    for (int newIdx = 0; newIdx < newCompleteFile.getProgramFrameCount(); newIdx++) {
      ProgramFrame newFrame = newCompleteFile.getProgramFrameAt(newIdx);

      // Check whether there is a counterpart in the last file
      int lastIdx = lastCompleteFile.getProgramFrameIndexForId(newFrame.getId());
      if (lastIdx == -1) {
        // There is no counterpart -> this is an insert
        ProgramFrame insertFrame = (ProgramFrame) newFrame.clone();
        updateFile.addProgramFrame(insertFrame);
      } else {
        // There is a counterpart -> this is an update
        // -> Determine the changed fields and add them
        ProgramFrame lastFrame = lastCompleteFile.getProgramFrameAt(lastIdx);
        ProgramFrame updateFrame = createUpdateFrame(lastFrame, newFrame);

        if (updateFrame != null) {
          updateFile.addProgramFrame(updateFrame);
        }
      }
    }

    return updateFile;
  }


  private ProgramFrame createUpdateFrame(ProgramFrame lastFrame,
    ProgramFrame newFrame)
  {
    ProgramFrame updateFrame = null;

    // Determine the fields that should be deleted
    for (int lastIdx = 0; lastIdx < lastFrame.getProgramFieldCount(); lastIdx++) {
      ProgramField lastField = lastFrame.getProgramFieldAt(lastIdx);

      // Check whether this field has an counterpart in the new frame
      int newIdx = newFrame.getProgramFieldIndexForTypeId(lastField.getTypeId());
      if (newIdx == -1) {
        // It has not -> Add an empty field with this type ID as a order for
        // deletion
        ProgramField updateField = (ProgramField) lastField.clone();
        updateField.removeData();

        if (updateFrame == null) {
          updateFrame = new ProgramFrame(newFrame.getId());
        }
        updateFrame.addProgramField(updateField);
      }
    }

    // Determine the programs that should be inserted or updated
    for (int newIdx = 0; newIdx < newFrame.getProgramFieldCount(); newIdx++) {
      ProgramField newField = newFrame.getProgramFieldAt(newIdx);

      // Check whether there is a counterpart in the last file and whether it
      // has changed
      int lastIdx = lastFrame.getProgramFieldIndexForTypeId(newField.getTypeId());

      boolean hasChanged;
      if (lastIdx == -1) {
        // There is no counterpart -> It has changed
        hasChanged = true;
      } else {
        // There is a counterpart -> Check whether the content changed
        ProgramField lastField = lastFrame.getProgramFieldAt(lastIdx);

        hasChanged = ! newField.equals(lastField);
      }

      // Add the field if it has changed
      if (hasChanged) {
        ProgramField field = (ProgramField) newField.clone();

        if (updateFrame == null) {
          updateFrame = new ProgramFrame(newFrame.getId());
        }
        updateFrame.addProgramField(field);
      }
    }

    return updateFrame;
  }


  private int getMaxIdOfUpdateFiles(Date date, String country,
    String channel, String level, File preparedDir)
    throws PreparationException
  {
    int maxId = 0;

    // Get the max IDs of all update files
    int updateVersion = 1;
    boolean finished = false;
    while (! finished) {
      String filename = DayProgramFile.getProgramFileName(date, country,
        channel, level, updateVersion);
      File file = new File(preparedDir, filename);
      if (! file.exists()) {
        finished = true;
      } else {
        DayProgramFile updateFile;
        try {
          updateFile = new DayProgramFile();
          updateFile.readFromFile(file);
        }
        catch (Exception exc) {
          throw new PreparationException("Loading prepared file failed: "
            + filename, exc);
        }

        // Get the max ID
        int updateMaxId = PrimaryDataUtilities.getMaxId(updateFile);
        if (updateMaxId > maxId) {
          maxId = updateMaxId;
        }
      }

      updateVersion++;
    }

    return maxId;
  }


  private void updateOldUpdateFiles(DayProgramFile newUpdateFile, Date date,
    String country, String channel, String level, File preparedDir, File targetDir)
    throws PreparationException
  {
    int newUpdateFileFromVersion = newUpdateFile.getVersion() - 1;
    for (int version = 1; version < newUpdateFileFromVersion; version++) {
      // Load the update file
      String updateFileName = DayProgramFile.getProgramFileName(date, country,
        channel, level, version);
      File file = new File(preparedDir, updateFileName);
      DayProgramFile updateFile;
      try {
        updateFile = new DayProgramFile();
        updateFile.readFromFile(file);
      }
      catch (Exception exc) {
        throw new PreparationException("Loading update file for version "
          + version + " failed: " + file.getAbsolutePath(), exc);
      }

      // Update the update file
      try {
        updateFile.updateUpdateFile(newUpdateFile);
      }
      catch (FileFormatException exc) {
        throw new PreparationException("Updating the update file for version "
          + version + " failed: " + updateFileName, exc);
      }

      // Save the update file
      file = new File(targetDir, updateFileName);
      try {
        updateFile.writeToFile(file);
      }
      catch (Exception exc) {
        throw new PreparationException("Writing update file for version "
          + version + " failed: " + file.getAbsolutePath(), exc);
      }
    }
  }


  private boolean checkForQuarantine(DayProgramFile oldProg, DayProgramFile newProg) {
    int oldFrameCount = oldProg.getProgramFrameCount();

    // Count the number of frames that will be deleted
    int deletedCount = 0;
    for (int i = 0; i < oldFrameCount; i++) {
      int oldFrameId = oldProg.getProgramFrameAt(i).getId();

      // Check whether there is a frame with this ID in the new program
      if (newProg.getProgramFrameIndexForId(oldFrameId) == -1) {
        // This frame is missing in the new program
        deletedCount++;
      }
    }

    int maxDeletedFrames = (int) (oldFrameCount * MAX_DELETED_FRAMES);
    return (deletedCount > maxDeletedFrames);
  }

}
TOP

Related Classes of primarydatamanager.RawDataProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.