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-2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.server.loggers;
028
029import java.io.File;
030import java.io.FilenameFilter;
031
032import org.forgerock.i18n.slf4j.LocalizedLogger;
033import org.opends.server.util.TimeThread;
034
035/**
036 * A file name policy that names files suffixed by the time it was created.
037 */
038public class TimeStampNaming implements FileNamingPolicy
039{
040  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
041
042  private File file;
043  private TimeStampNamingFilter filter;
044
045  /**
046   * The FilenameFilter implementation for this naming policy to filter
047   * for all the files named by this policy.
048   */
049  private class TimeStampNamingFilter implements FilenameFilter
050  {
051    /**
052     * Select only files that are named by this policy.
053     *
054     * @param dir  The directory to search.
055     * @param name The filename to which to apply the filter.
056     *
057     * @return  <CODE>true</CODE> if the given filename matches the filter, or
058     *          <CODE>false</CODE> if it does not.
059     */
060    public boolean accept(File dir, String name)
061    {
062      if(new File(dir, name).isDirectory())
063      {
064        return false;
065      }
066
067      String initialFileName = file.getName();
068
069      // Make sure it is the expected length.
070      if(name.length() != initialFileName.length() + 16)
071      {
072        return false;
073      }
074
075      int pos;
076      // Make sure we got the expected name prefix.
077      for(pos = 0; pos < initialFileName.length(); pos++)
078      {
079        if(name.charAt(pos) != initialFileName.charAt(pos))
080        {
081          return false;
082        }
083      }
084
085      // Make sure there is a period between the prefix and timestamp.
086      if(name.charAt(pos) != '.')
087      {
088        return false;
089      }
090
091      char c;
092      // Make sure there are 14 numbers for the timestamp.
093      for(pos++; pos < name.length() - 1; pos++)
094      {
095        c = name.charAt(pos);
096        if(c < 48 || c > 57)
097        {
098          return false;
099        }
100      }
101
102      // And ends with an Z.
103      return name.charAt(pos) == 'Z';
104
105    }
106  }
107
108  /**
109   * Create a new instance of the TimeStampNaming policy. Files will be created
110   * with the names in the prefix.utctime format.
111   *
112   * @param file the file to use as the naming prefix.
113   */
114  public TimeStampNaming(File file)
115  {
116    this.file = file;
117    this.filter = new TimeStampNamingFilter();
118  }
119
120  /** {@inheritDoc} */
121  public File getInitialName()
122  {
123    return file;
124  }
125
126  /** {@inheritDoc} */
127  public File getNextName()
128  {
129    return new File(file + "." + TimeThread.getGMTTime());
130  }
131
132  /** {@inheritDoc} */
133  public FilenameFilter getFilenameFilter()
134  {
135    return filter;
136  }
137
138  /** {@inheritDoc} */
139  public File[] listFiles()
140  {
141    File directory = file.getParentFile();
142    File[] files =  directory.listFiles(filter);
143
144    if(files == null)
145    {
146      logger.trace("Unable to list files named by policy " +
147          "with initial file %s in directory %s", file, directory);
148    }
149
150    return files;
151  }
152
153}