001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2006-2008 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2015 ForgeRock AS.
016 */
017package org.opends.server.loggers;
018import java.util.Arrays;
019import java.util.Calendar;
020import java.util.List;
021
022import org.forgerock.i18n.LocalizableMessage;
023import org.forgerock.i18n.slf4j.LocalizedLogger;
024import org.opends.server.admin.server.ConfigurationChangeListener;
025import org.opends.server.admin.std.server.FixedTimeLogRotationPolicyCfg;
026import org.forgerock.opendj.config.server.ConfigChangeResult;
027import org.opends.server.util.TimeThread;
028
029/**
030 * This class implements a rotation policy based on fixed day/time of day.
031 */
032public class FixedTimeRotationPolicy implements
033    RotationPolicy<FixedTimeLogRotationPolicyCfg>,
034    ConfigurationChangeListener<FixedTimeLogRotationPolicyCfg>
035{
036  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
037
038  /** The scheduled rotation times as ms offsets from the beginning of the day. */
039  private int[] rotationTimes;
040
041  /** {@inheritDoc} */
042  public void initializeLogRotationPolicy(FixedTimeLogRotationPolicyCfg config)
043  {
044    rotationTimes = new int[config.getTimeOfDay().size()];
045
046    int i = 0;
047    for(String time : config.getTimeOfDay())
048    {
049      rotationTimes[i++] = Integer.valueOf(time);
050    }
051
052    Arrays.sort(rotationTimes);
053
054    config.addFixedTimeChangeListener(this);
055  }
056
057  /** {@inheritDoc} */
058  public boolean isConfigurationChangeAcceptable(
059      FixedTimeLogRotationPolicyCfg config, List<LocalizableMessage> unacceptableReasons)
060  {
061    // Changes should always be OK
062    return true;
063  }
064
065  /** {@inheritDoc} */
066  public ConfigChangeResult applyConfigurationChange(
067      FixedTimeLogRotationPolicyCfg config)
068  {
069    final ConfigChangeResult ccr = new ConfigChangeResult();
070
071    rotationTimes = new int[config.getTimeOfDay().size()];
072
073    int i = 0;
074    for(String time : config.getTimeOfDay())
075    {
076      rotationTimes[i++] = Integer.valueOf(time);
077    }
078
079    Arrays.sort(rotationTimes);
080
081    return ccr;
082  }
083
084  /** {@inheritDoc} */
085  public boolean rotateFile(RotatableLogFile writer)
086  {
087    Calendar lastRotationTime = writer.getLastRotationTime();
088
089    Calendar nextRotationTime = (Calendar)lastRotationTime.clone();
090    int i = 0;
091    nextRotationTime.set(Calendar.HOUR_OF_DAY, rotationTimes[i] / 100);
092    nextRotationTime.set(Calendar.MINUTE, rotationTimes[i] % 100);
093    nextRotationTime.set(Calendar.SECOND, 0);
094    while(lastRotationTime.after(nextRotationTime))
095    {
096      if(i == rotationTimes.length - 1)
097      {
098        nextRotationTime.add(Calendar.DATE, 1);
099        i = 0;
100      }
101      else
102      {
103        i++;
104      }
105
106      nextRotationTime.set(Calendar.HOUR_OF_DAY, rotationTimes[i] / 100);
107      nextRotationTime.set(Calendar.MINUTE, rotationTimes[i] % 100);
108    }
109
110    logger.trace("The next fixed rotation time is %s", rotationTimes[i]);
111
112    return TimeThread.getCalendar().after(nextRotationTime);
113  }
114}
115