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
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.loggers;
028    import org.opends.messages.Message;
029    
030    import java.util.*;
031    
032    import org.opends.server.util.TimeThread;
033    
034    import static org.opends.server.loggers.debug.DebugLogger.*;
035    import org.opends.server.loggers.debug.DebugTracer;
036    import org.opends.server.admin.std.server.FixedTimeLogRotationPolicyCfg;
037    import org.opends.server.admin.server.ConfigurationChangeListener;
038    import org.opends.server.types.ConfigChangeResult;
039    import org.opends.server.types.ResultCode;
040    
041    
042    /**
043     * This class implements a rotation policy based on fixed
044     * day/time of day.
045     */
046    public class FixedTimeRotationPolicy implements
047        RotationPolicy<FixedTimeLogRotationPolicyCfg>,
048        ConfigurationChangeListener<FixedTimeLogRotationPolicyCfg>
049    {
050      /**
051       * The tracer object for the debug logger.
052       */
053      private static final DebugTracer TRACER = getTracer();
054    
055    
056      private static final long MS_IN_DAY = 24 * 3600 * 1000;
057    
058      // The scheduled rotation times as ms offsets from the beginnging of the day.
059      private int[] rotationTimes;
060    
061      /**
062       * {@inheritDoc}
063       */
064      public void initializeLogRotationPolicy(FixedTimeLogRotationPolicyCfg config)
065      {
066        rotationTimes = new int[config.getTimeOfDay().size()];
067    
068        int i = 0;
069        for(String time : config.getTimeOfDay())
070        {
071          rotationTimes[i++] = Integer.valueOf(time);
072        }
073    
074        Arrays.sort(rotationTimes);
075    
076        config.addFixedTimeChangeListener(this);
077      }
078    
079      /**
080       * {@inheritDoc}
081       */
082      public boolean isConfigurationChangeAcceptable(
083          FixedTimeLogRotationPolicyCfg config, List<Message> unacceptableReasons)
084      {
085        // Changes should always be OK
086        return true;
087      }
088    
089      /**
090       * {@inheritDoc}
091       */
092      public ConfigChangeResult applyConfigurationChange(
093          FixedTimeLogRotationPolicyCfg config)
094      {
095        // Default result code.
096        ResultCode resultCode = ResultCode.SUCCESS;
097        boolean adminActionRequired = false;
098        ArrayList<Message> messages = new ArrayList<Message>();
099    
100        rotationTimes = new int[config.getTimeOfDay().size()];
101    
102        int i = 0;
103        for(String time : config.getTimeOfDay())
104        {
105          rotationTimes[i++] = Integer.valueOf(time);
106        }
107    
108        Arrays.sort(rotationTimes);
109    
110        return new ConfigChangeResult(resultCode, adminActionRequired, messages);
111      }
112    
113      /**
114       * {@inheritDoc}
115       */
116      public boolean rotateFile(MultifileTextWriter writer)
117      {
118        Calendar lastRotationTime = writer.getLastRotationTime();
119    
120        Calendar nextRotationTime = (Calendar)lastRotationTime.clone();
121        int i = 0;
122        nextRotationTime.set(Calendar.HOUR_OF_DAY, rotationTimes[i] / 100);
123        nextRotationTime.set(Calendar.MINUTE, rotationTimes[i] % 100);
124        nextRotationTime.set(Calendar.SECOND, 0);
125        while(lastRotationTime.after(nextRotationTime))
126        {
127          if(i == rotationTimes.length - 1)
128          {
129            nextRotationTime.add(Calendar.DATE, 1);
130            i = 0;
131          }
132          else
133          {
134            i++;
135          }
136    
137          nextRotationTime.set(Calendar.HOUR_OF_DAY, rotationTimes[i] / 100);
138          nextRotationTime.set(Calendar.MINUTE, rotationTimes[i] % 100);
139        }
140    
141        if (debugEnabled())
142        {
143          TRACER.debugInfo("The next fixed rotation time is %s", rotationTimes[i]);
144        }
145    
146        return TimeThread.getCalendar().after(nextRotationTime);
147      }
148    }
149