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.tools.makeldif;
018import org.forgerock.i18n.LocalizableMessage;
019
020
021
022import java.io.File;
023import java.io.IOException;
024import java.util.List;
025import java.util.Random;
026
027import org.opends.server.types.InitializationException;
028
029import static org.opends.messages.ToolMessages.*;
030
031
032
033/**
034 * This class defines a tag that is used provide values from a text file.  The
035 * file should have one value per line.  Access to the values may be either at
036 * random or in sequential order.
037 */
038public class FileTag
039       extends Tag
040{
041  /** Indicates whether the values should be selected sequentially or at random. */
042  private boolean sequential;
043
044  /** The file containing the data. */
045  private File dataFile;
046
047  /** The index used for sequential access. */
048  private int nextIndex;
049
050  /** The random number generator for this tag. */
051  private Random random;
052
053  /** The array of lines read from the file. */
054  private String[] fileLines;
055
056
057
058  /**
059   * Creates a new instance of this file tag.
060   */
061  public FileTag()
062  {
063    sequential = false;
064    dataFile   = null;
065    nextIndex  = 0;
066    random     = null;
067    fileLines  = null;
068  }
069
070
071
072  /**
073   * Retrieves the name for this tag.
074   *
075   * @return  The name for this tag.
076   */
077  public String getName()
078  {
079    return "File";
080  }
081
082
083
084  /**
085   * Indicates whether this tag is allowed for use in the extra lines for
086   * branches.
087   *
088   * @return  <CODE>true</CODE> if this tag may be used in branch definitions,
089   *          or <CODE>false</CODE> if not.
090   */
091  public boolean allowedInBranch()
092  {
093    return true;
094  }
095
096
097
098  /**
099   * Performs any initialization for this tag that may be needed while parsing
100   * a branch definition.
101   *
102   * @param  templateFile  The template file in which this tag is used.
103   * @param  branch        The branch in which this tag is used.
104   * @param  arguments     The set of arguments provided for this tag.
105   * @param  lineNumber    The line number on which this tag appears in the
106   *                       template file.
107   * @param  warnings      A list into which any appropriate warning messages
108   *                       may be placed.
109   *
110   * @throws  InitializationException  If a problem occurs while initializing
111   *                                   this tag.
112   */
113  public void initializeForBranch(TemplateFile templateFile, Branch branch,
114                                  String[] arguments, int lineNumber,
115                                  List<LocalizableMessage> warnings)
116         throws InitializationException
117  {
118    initializeInternal(templateFile, arguments, lineNumber, warnings);
119  }
120
121
122
123  /**
124   * Performs any initialization for this tag that may be needed while parsing
125   * a template definition.
126   *
127   * @param  templateFile  The template file in which this tag is used.
128   * @param  template      The template in which this tag is used.
129   * @param  arguments     The set of arguments provided for this tag.
130   * @param  lineNumber    The line number on which this tag appears in the
131   *                       template file.
132   * @param  warnings      A list into which any appropriate warning messages
133   *                       may be placed.
134   *
135   * @throws  InitializationException  If a problem occurs while initializing
136   *                                   this tag.
137   */
138  public void initializeForTemplate(TemplateFile templateFile,
139                                    Template template, String[] arguments,
140                                    int lineNumber, List<LocalizableMessage> warnings)
141         throws InitializationException
142  {
143    initializeInternal(templateFile, arguments, lineNumber, warnings);
144  }
145
146
147
148  /**
149   * Performs any initialization for this tag that may be needed.
150   *
151   * @param  templateFile  The template file in which this tag is used.
152   * @param  arguments     The set of arguments provided for this tag.
153   * @param  lineNumber    The line number on which this tag appears in the
154   *                       template file.
155   * @param  warnings      A list into which any appropriate warning messages
156   *                       may be placed.
157   *
158   * @throws  InitializationException  If a problem occurs while initializing
159   *                                   this tag.
160   */
161  private void initializeInternal(TemplateFile templateFile, String[] arguments,
162                                  int lineNumber, List<LocalizableMessage> warnings)
163          throws InitializationException
164  {
165    random = templateFile.getRandom();
166
167
168    // There must be at least one argument, and possibly two.
169    if (arguments.length < 1 || arguments.length > 2)
170    {
171      LocalizableMessage message = ERR_MAKELDIF_TAG_INVALID_ARGUMENT_RANGE_COUNT.get(
172          getName(), lineNumber, 1, 2, arguments.length);
173      throw new InitializationException(message);
174    }
175
176
177    // The first argument should be the path to the file.
178    dataFile = templateFile.getFile(arguments[0]);
179    if (dataFile == null || !dataFile.exists())
180    {
181      LocalizableMessage message = ERR_MAKELDIF_TAG_CANNOT_FIND_FILE.get(
182          arguments[0], getName(), lineNumber);
183      throw new InitializationException(message);
184    }
185
186
187    // If there is a second argument, then it should be either "sequential" or
188    // "random".  If there isn't one, then we should assume "random".
189    if (arguments.length == 2)
190    {
191      if (arguments[1].equalsIgnoreCase("sequential"))
192      {
193        sequential = true;
194        nextIndex  = 0;
195      }
196      else if (arguments[1].equalsIgnoreCase("random"))
197      {
198        sequential = false;
199      }
200      else
201      {
202        LocalizableMessage message = ERR_MAKELDIF_TAG_INVALID_FILE_ACCESS_MODE.get(
203            arguments[1], getName(), lineNumber);
204        throw new InitializationException(message);
205      }
206    }
207    else
208    {
209      sequential = false;
210    }
211
212
213    // See if the file has already been read into memory.  If not, then read it.
214    try
215    {
216      fileLines = templateFile.getFileLines(dataFile);
217    }
218    catch (IOException ioe)
219    {
220      LocalizableMessage message = ERR_MAKELDIF_TAG_CANNOT_READ_FILE.get(
221          arguments[0], getName(), lineNumber, ioe);
222      throw new InitializationException(message, ioe);
223    }
224  }
225
226
227
228  /**
229   * Generates the content for this tag by appending it to the provided tag.
230   *
231   * @param  templateEntry  The entry for which this tag is being generated.
232   * @param  templateValue  The template value to which the generated content
233   *                        should be appended.
234   *
235   * @return  The result of generating content for this tag.
236   */
237  public TagResult generateValue(TemplateEntry templateEntry,
238                                 TemplateValue templateValue)
239  {
240    if (sequential)
241    {
242      templateValue.append(fileLines[nextIndex++]);
243      if (nextIndex >= fileLines.length)
244      {
245        nextIndex = 0;
246      }
247    }
248    else
249    {
250      templateValue.append(fileLines[random.nextInt(fileLines.length)]);
251    }
252
253    return TagResult.SUCCESS_RESULT;
254  }
255}
256