001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2008 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.server.loggers;
028import static org.opends.messages.LoggerMessages.*;
029
030import java.io.File;
031import java.util.ArrayList;
032import java.util.Arrays;
033import java.util.List;
034
035import org.forgerock.i18n.LocalizableMessage;
036import org.opends.server.admin.server.ConfigurationChangeListener;
037import org.opends.server.admin.std.server.FileCountLogRetentionPolicyCfg;
038import org.opends.server.core.DirectoryServer;
039import org.forgerock.opendj.config.server.ConfigChangeResult;
040import org.opends.server.types.DirectoryException;
041
042
043/**
044 * This class implements a retention policy based on the number of files.
045 * Files will be cleaned up based on the number of files on disk.
046 */
047public class FileNumberRetentionPolicy implements
048    RetentionPolicy<FileCountLogRetentionPolicyCfg>,
049    ConfigurationChangeListener<FileCountLogRetentionPolicyCfg>
050{
051
052  private int numFiles;
053  private FileCountLogRetentionPolicyCfg config;
054
055  /** {@inheritDoc} */
056  public void initializeLogRetentionPolicy(
057      FileCountLogRetentionPolicyCfg config)
058  {
059    this.numFiles = config.getNumberOfFiles();
060    this.config = config;
061
062    config.addFileCountChangeListener(this);
063  }
064
065  /** {@inheritDoc} */
066  public boolean isConfigurationChangeAcceptable(
067      FileCountLogRetentionPolicyCfg config,
068      List<LocalizableMessage> unacceptableReasons)
069  {
070    // Changes should always be OK
071    return true;
072  }
073
074  /** {@inheritDoc} */
075  public ConfigChangeResult applyConfigurationChange(
076      FileCountLogRetentionPolicyCfg config)
077  {
078    this.numFiles = config.getNumberOfFiles();
079    this.config = config;
080    return new ConfigChangeResult();
081  }
082
083  /** {@inheritDoc} */
084  public File[] deleteFiles(FileNamingPolicy fileNamingPolicy)
085      throws DirectoryException
086  {
087    File[] files = fileNamingPolicy.listFiles();
088    if(files == null)
089    {
090      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(),
091          ERR_LOGGER_ERROR_LISTING_FILES.get(fileNamingPolicy.getInitialName()));
092    }
093
094    if (files.length <= numFiles)
095    {
096      return new File[0];
097    }
098
099    // Sort files based on last modified time.
100    Arrays.sort(files, new FileComparator());
101
102    ArrayList<File> filesToDelete = new ArrayList<>();
103    for (int j = numFiles; j < files.length; j++)
104    {
105      filesToDelete.add(files[j]);
106    }
107    return filesToDelete.toArray(new File[0]);
108  }
109
110  /** {@inheritDoc} */
111  public String toString()
112  {
113    return "Free Number Retention Policy " + config.dn();
114  }
115}
116