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-2016 ForgeRock AS.
016 */
017package org.opends.server.tools.makeldif;
018
019import java.io.File;
020import java.io.IOException;
021import java.util.List;
022import java.util.Random;
023
024import org.forgerock.i18n.LocalizableMessage;
025import org.opends.server.types.InitializationException;
026
027import static org.opends.messages.ToolMessages.*;
028
029/**
030 * This class defines a tag that is used provide values from a text file.  The
031 * file should have one value per line.  Access to the values may be either at
032 * random or in sequential order.
033 */
034public class FileTag
035       extends Tag
036{
037  /** Indicates whether the values should be selected sequentially or at random. */
038  private boolean sequential;
039
040  /** The file containing the data. */
041  private File dataFile;
042
043  /** The index used for sequential access. */
044  private int nextIndex;
045
046  /** The random number generator for this tag. */
047  private Random random;
048
049  /** The array of lines read from the file. */
050  private String[] fileLines;
051
052  /** Creates a new instance of this file tag. */
053  public FileTag()
054  {
055    sequential = false;
056    dataFile   = null;
057    nextIndex  = 0;
058    random     = null;
059    fileLines  = null;
060  }
061
062  @Override
063  public String getName()
064  {
065    return "File";
066  }
067
068  @Override
069  public boolean allowedInBranch()
070  {
071    return true;
072  }
073
074  @Override
075  public void initializeForBranch(TemplateFile templateFile, Branch branch,
076                                  String[] arguments, int lineNumber,
077                                  List<LocalizableMessage> warnings)
078         throws InitializationException
079  {
080    initializeInternal(templateFile, arguments, lineNumber, warnings);
081  }
082
083  @Override
084  public void initializeForTemplate(TemplateFile templateFile,
085                                    Template template, String[] arguments,
086                                    int lineNumber, List<LocalizableMessage> warnings)
087         throws InitializationException
088  {
089    initializeInternal(templateFile, arguments, lineNumber, warnings);
090  }
091
092  private void initializeInternal(TemplateFile templateFile, String[] arguments,
093                                  int lineNumber, List<LocalizableMessage> warnings)
094          throws InitializationException
095  {
096    random = templateFile.getRandom();
097
098
099    // There must be at least one argument, and possibly two.
100    if (arguments.length < 1 || arguments.length > 2)
101    {
102      LocalizableMessage message = ERR_MAKELDIF_TAG_INVALID_ARGUMENT_RANGE_COUNT.get(
103          getName(), lineNumber, 1, 2, arguments.length);
104      throw new InitializationException(message);
105    }
106
107
108    // The first argument should be the path to the file.
109    dataFile = templateFile.getFile(arguments[0]);
110    if (dataFile == null || !dataFile.exists())
111    {
112      LocalizableMessage message = ERR_MAKELDIF_TAG_CANNOT_FIND_FILE.get(
113          arguments[0], getName(), lineNumber);
114      throw new InitializationException(message);
115    }
116
117
118    // If there is a second argument, then it should be either "sequential" or
119    // "random".  If there isn't one, then we should assume "random".
120    if (arguments.length == 2)
121    {
122      if (arguments[1].equalsIgnoreCase("sequential"))
123      {
124        sequential = true;
125        nextIndex  = 0;
126      }
127      else if (arguments[1].equalsIgnoreCase("random"))
128      {
129        sequential = false;
130      }
131      else
132      {
133        LocalizableMessage message = ERR_MAKELDIF_TAG_INVALID_FILE_ACCESS_MODE.get(
134            arguments[1], getName(), lineNumber);
135        throw new InitializationException(message);
136      }
137    }
138    else
139    {
140      sequential = false;
141    }
142
143
144    // See if the file has already been read into memory.  If not, then read it.
145    try
146    {
147      fileLines = templateFile.getFileLines(dataFile);
148    }
149    catch (IOException ioe)
150    {
151      LocalizableMessage message = ERR_MAKELDIF_TAG_CANNOT_READ_FILE.get(
152          arguments[0], getName(), lineNumber, ioe);
153      throw new InitializationException(message, ioe);
154    }
155  }
156
157  @Override
158  public TagResult generateValue(TemplateEntry templateEntry,
159                                 TemplateValue templateValue)
160  {
161    if (sequential)
162    {
163      templateValue.append(fileLines[nextIndex++]);
164      if (nextIndex >= fileLines.length)
165      {
166        nextIndex = 0;
167      }
168    }
169    else
170    {
171      templateValue.append(fileLines[random.nextInt(fileLines.length)]);
172    }
173
174    return TagResult.SUCCESS_RESULT;
175  }
176}